home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / gnushogi.lha / gnushogi-1.1 / src / eval.c < prev    next >
C/C++ Source or Header  |  1993-04-27  |  70KB  |  2,759 lines

  1. /*
  2.  * eval.c - C source for GNU SHOGI
  3.  *
  4.  * Copyright (c) 1993 Matthias Mutz
  5.  *
  6.  * GNU SHOGI is based on GNU CHESS
  7.  *
  8.  * Copyright (c) 1988,1989,1990 John Stanback
  9.  * Copyright (c) 1992 Free Software Foundation
  10.  *
  11.  * This file is part of GNU Shogi.
  12.  *
  13.  * GNU Shogi is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 1, or (at your option)
  16.  * any later version.
  17.  *
  18.  * GNU Shogi is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with GNU Shogi; see the file COPYING.  If not, write to
  25.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  */
  27. #include "gnushogi.h"
  28. #include "ataks.h" 
  29.  
  30. #ifdef USE_PATTERN
  31. #include "pattern.h"
  32. #endif
  33.  
  34. #ifdef THINK_C
  35. #include <string.h>
  36. #define bcopy(src,dst,len) memcpy(dst,src,len)
  37. #endif
  38.  
  39. #if !defined K32SEGMENTS
  40. #include "eval_data1.c"
  41. #endif
  42.  
  43. int EADD = 0;
  44. int EGET = 0;
  45.  
  46.  
  47. #ifdef DEBUG_EVAL
  48. extern short debug_eval;
  49. extern FILE *debug_eval_file;
  50. #endif
  51.  
  52.  
  53. static short in_opening_stage = true;
  54. static short behind_in_material[2] = {false, false};
  55.  
  56.  
  57. /* distance to enemy king */
  58. static const EnemyKingDistanceBonus[9] =
  59. {0, 20, 15, 8, 5, 3, 1, 0, 0};
  60.  
  61. /* distance to own king */
  62. static const OwnKingDistanceBonus[9] =
  63. {0, 10, 4, 1, 0, 0, 0, 0, 0};
  64.  
  65. /* distance to promotion zone */
  66. static const PromotionZoneDistanceBonus[NO_ROWS] =
  67. {0, 0, 0, 0, 4, 8, 10, 10, 10};
  68.  
  69. /* Bishop mobility bonus indexed by # reachable squares */
  70. static const short BMBLTY[20] =
  71. {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 16, 16, 16, 16};
  72.  
  73. /* Rook mobility bonus indexed by # reachable squares */
  74. static const short RMBLTY[20] =
  75. {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 16, 16, 16, 16};
  76.  
  77. /* Lance mobility bonus indexed by # reachable squares */
  78. static const short LMBLTY[8] =
  79. {0, 0, 0, 0, 1, 2, 4, 8};
  80.  
  81.  
  82. /* penalty for threats to king, indexed by number of such threats */
  83. static const short KTHRT[36] =
  84. {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
  85.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
  86.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
  87.  
  88.  
  89. /* No positional bonus ! */
  90. static const short NoAdvance[NO_SQUARES] =
  91. {  0,  0,  0,  0,  0,  0,  0,  0,  0,
  92.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  93.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  94.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  95.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  96.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  97.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  98.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  99.    0,  0,  0,  0,  0,  0,  0,  0,  0 };
  100.  
  101. /* Pawn positional bonus (STATIC ROOK vs. STATIC ROOK) */
  102. static const short PawnAdvanceSS[NO_SQUARES] =
  103. {  0,  0,  0,  0,  0,  0,  0,  0,  0,
  104.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  105.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  106.    3, -2, 15,  4,  6,  1,  6,  8,  3, 
  107.    0, -5, -5,  0,  0,  0,  5, 10,  5, 
  108.    0,  0,  0,  0,  0,  0,  0,  0, 10, 
  109.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  110.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  111.    0,  0,  0,  0,  0,  0,  0,  0,  0 };
  112.  
  113. #define PawnAdvanceSR PawnAdvanceSS
  114.  
  115. /* Pawn positional bonus (RANGING ROOK vs. STATIC ROOK) */
  116. static const short PawnAdvanceRS[NO_SQUARES] =
  117. {  0,  0,  0,  0,  0,  0,  0,  0,  0,
  118.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  119.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  120.    3, -2, 15,  3,  5,  0, -2, -4,  3, 
  121.    1,  0,  8,  3,  5,  2,  2, -2, -2, 
  122.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  123.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  124.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  125.    0,  0,  0,  0,  0,  0,  0,  0,  0 };
  126.  
  127. #define PawnAdvanceRR PawnAdvanceRS
  128.  
  129. /* Lance positional bonus (STATIC ROOK vs. STATIC ROOK) */
  130. short LanceAdvanceSS[NO_SQUARES] =
  131. { 10,  5,  5,  5,  5,  5,  5,  5, 10,
  132.    2,  4,  4,  4,  4,  4,  4,  4,  2,
  133.    4,  1,  1,  1,  1,  1,  1,  1,  4,
  134.   -2, -2, -2, -2, -2, -2, -2, -2, -2, 
  135.   -4, -4, -4, -4, -4, -4, -4, -4, -4, 
  136.   -6, -6, -6, -6, -6, -6, -6, -6, -6,
  137.   -8, -8, -8, -8, -8, -8, -8, -8, -8, 
  138.   -9, -9, -9, -9, -9, -9, -9, -9, -9, 
  139.    0,  0,  0,  0,  0,  0,  0,  0,  0 }; /* impossible */
  140.  
  141. #define LanceAdvanceSR LanceAdvanceSS
  142. #define LanceAdvanceRS LanceAdvanceSS
  143. #define LanceAdvanceRR LanceAdvanceRS
  144.  
  145. /* Knight positional bonus (STATIC ROOK vs. STATIC ROOK) */
  146. short KnightAdvanceSS[NO_SQUARES] =
  147. {-9,  4,  4,  4, 4, 4, 4, 4,-9,
  148.  -9,  2,  2,  2, 2, 2, 2, 2,-9,
  149.  -9,  1,-10,  1, 1, 1, 1, 1,-9,
  150.  -9,  0,  0,  0, 0, 0, 0, 0,-9,
  151.  -9, -5,  0, -5, 0,-5, 0,-5,-9
  152.  -9,  0,  0,  0, 0, 0, 0, 0,-9,
  153.  -9, -9, -9, -9,-9,-9,-9,-9,-9,
  154.   0,  0,  0,  0, 0, 0, 0, 0, 0,  /* impossible */
  155.   0,  0,  0,  0, 0, 0, 0, 0, 0 };/* impossible */
  156.  
  157. #define KnightAdvanceSR KnightAdvanceSS
  158. #define KnightAdvanceRS KnightAdvanceSS
  159. #define KnightAdvanceRR KnightAdvanceRS
  160.  
  161. /* Silver positional bonus (STATIC ROOK vs. STATIC ROOK) */
  162. short SilverAdvanceSS[NO_SQUARES] =
  163. {  0,  0,  0,  0, -6,  0,  0,  0,  0,
  164.    0,  8,  3,  4,  0,  3,  2,  0,  0, 
  165.    0,  0, 10,  0,  0,  6,  6,  4,  0, 
  166.    0,  0,  0,  0,  4,  0,  4,  5,  0,
  167.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  168.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  169.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  170.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  171.    0,  0,  0,  0,  0,  0,  0,  0,  0 };
  172.  
  173. /* Silver positional bonus (STATIC ROOK vs. RANGING ROOK) */
  174. short SilverAdvanceSR[NO_SQUARES] =
  175. {  0,  0,  0,  0, -6,  0,  0,  0,  0,
  176.    0, -4, -4,  4,  0,  5,  3,  0,  0, 
  177.    0,  0, -4, -4,  2,  8,  6,  0,  0, 
  178.    0,  0,  0,  3,  0,  0,  4,  0,  0,
  179.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  180.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  181.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  182.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  183.    0,  0,  0,  0,  0,  0,  0,  0,  0 };
  184.  
  185. /* Silver positional bonus (RANGING ROOK vs. STATIC ROOK) */
  186. short SilverAdvanceRS[NO_SQUARES] =
  187. { -3,  0,  0,  0,  0,  0,  0,  0, -2,
  188.   -3, -1,  3,  3, -1, -1,  8, -1, -2, 
  189.   -2, -2,  0,  5, -1,  9, -2,  5, -3, 
  190.    0,  0,  5,  2,  5,  0,  0,  0,  0,
  191.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  192.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  193.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  194.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  195.    0,  0,  0,  0,  0,  0,  0,  0,  0 };
  196.  
  197. #define SilverAdvanceRR SilverAdvanceRS 
  198.  
  199. /* Gold positional bonus (STATIC ROOK vs. STATIC ROOK) */
  200. short GoldAdvanceSS[NO_SQUARES] =
  201. {  0,  0,  0,  0,  0,  0,  0,  0,  0,
  202.    0,  0, 10,  0,  6,  0,  0,  0,  0, 
  203.    0,  0,  0,  8,  0,  0,  0,  0,  0, 
  204.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  205.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  206.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  207.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  208.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  209.    0,  0,  0,  0,  0,  0,  0,  0,  0 };
  210.  
  211. /* Gold positional bonus (STATIC ROOK vs. RANGING ROOK) */
  212. short GoldAdvanceSR[NO_SQUARES] =
  213. {  0,  0,  0, 10,  0,  0,  0,  0,  0,
  214.    0,  0,  0,  0,  6,  0,  0,  0,  0, 
  215.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  216.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  217.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  218.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  219.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  220.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  221.    0,  0,  0,  0,  0,  0,  0,  0,  0 };
  222.  
  223. /* Gold positional bonus (RANGING ROOK vs. STATIC ROOK) */
  224. short GoldAdvanceRS[NO_SQUARES] =
  225. { -1,  0, -1,  0, -1,  0, -1, -1, -1,
  226.   -1,  0,  4, -1,  4, -1,  8,  0, -1, 
  227.   -2, -1,  0, -2,  0,  6,  0, -1, -2, 
  228.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  229.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  230.    0,  0,  0,  0,  0,  0,  0,  0,  0,
  231.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  232.    0,  0,  0,  0,  0,  0,  0,  0,  0, 
  233.    0,  0,  0,  0,  0,  0,  0,  0,  0 };
  234.  
  235. #define GoldAdvanceRR GoldAdvanceRS
  236.  
  237. /* Bishop positional bonus (STATIC ROOK vs. STATIC ROOK) */
  238. short BishopAdvanceSS[NO_SQUARES] =
  239. {  3,  0,  0,  0,  0,  0,  0,  0,  3,
  240.    0,  4,  0,  8,  0,  0,  0,  3,  0, 
  241.    0,  0,  6,  0,  0,  0,  4,  0,  0, 
  242.    0,  2,  0,  3,  0,  3,  0,  2,  0,
  243.    0,  0,  2,  0,  3,  0,  0,  0,  0, 
  244.    0,  2,  0,  3,  0,  3,  0,  2,  0,
  245.    0,  0,  3,  0,  0,  0,  3,  0,  0, 
  246.    0,  3,  0,  0,  0,  0,  0,  3,  0, 
  247.    3,  0,  0,  0,  0,  0,  0,  0,  3 };
  248.  
  249. /* Bishop positional bonus (STATIC ROOK vs. RANGING ROOK) */
  250. short BishopAdvanceSR[NO_SQUARES] =
  251. {  3,  0,  0,  0,  0,  0,  0,  0,  3,
  252.    0, 10,  0,  2,  0,  0,  0,  3,  0, 
  253.    0,  0,  2,  0,  0,  0,  4,  0,  0, 
  254.    0,  2,  0,  3,  0,  3,  0,  2,  0,
  255.    0,  0,  2,  0,  3,  0,  0,  0,  0, 
  256.    0,  2,  0,  3,  0,  3,  0,  2,  0,
  257.    0,  0,  3,  0,  0,  0,  3,  0,  0, 
  258.    0,  3,  0,  0,  0,  0,  0,  3,  0, 
  259.    3,  0,  0,  0,  0,  0,  0,  0,  3 };
  260.  
  261. /* Bishop positional bonus (RANGING ROOK vs. STATIC ROOK) */
  262. short BishopAdvanceRS[NO_SQUARES] =
  263. {  3,  0,  0,  0,  0,  0,  0,  0,  3,
  264.    0,  4,  0,  2,  0,  0,  0,  3,  0, 
  265.    0,  0,  8,  0,  0,  0,  4,  0,  0, 
  266.    0,  2,  0,  3,  0,  3,  0,  2,  0,
  267.    0,  0,  2,  0,  3,  0,  0,  0,  0, 
  268.    0,  2,  0,  3,  0,  3,  0,  2,  0,
  269.    0,  0,  3,  0,  0,  0,  3,  0,  0, 
  270.    0,  3,  0,  0,  0,  0,  0,  3,  0, 
  271.    3,  0,  0,  0,  0,  0,  0,  0,  3 };
  272.  
  273. #define BishopAdvanceRR BishopAdvanceRS
  274.  
  275. /* Rook positional bonus (STATIC ROOK vs. STATIC ROOK) */
  276. short RookAdvanceSS[NO_SQUARES] =
  277. {  2,  0,  0,  0,  0,  0,  0,  4,  2,
  278.    2,  0,  0,  0,  0,  0,  0,  8,  2, 
  279.   -2,  0,  0,  0,  0,  0,  0,  2, -2, 
  280.   -2,  0,  0,  0,  0,  0,  0,  4, -2,
  281.   -2,  0,  0,  0,  0,  0,  0,  2, -2, 
  282.   -2,  0,  0,  0,  0,  0,  0,  2, -2,
  283.    4,  4,  4,  4,  4,  4,  4,  4,  4, 
  284.    6,  6,  6,  6,  6,  6,  6,  6,  6, 
  285.    8,  8,  8,  8,  8,  8,  8,  8,  8 };
  286.  
  287. /* Rook positional bonus (RANING ROOK vs. STATIC ROOK) */
  288. short RookAdvanceRS[NO_SQUARES] =
  289. {  2,  6,  6,  6,  6,  0,  0,  0,  2,
  290.    2,  4,  4,  4,  4,  0,  0,  0,  2, 
  291.   -2,  2,  3,  3,  3,  0,  0,  0, -2, 
  292.   -2,  4,  1,  1,  1,  0,  0,  0, -2,
  293.   -2,  0,  2,  2,  2,  0,  0,  0, -2, 
  294.   -2,  0,  0,  0,  0,  0,  0,  0, -2,
  295.    4,  4,  4,  4,  4,  4,  4,  4,  4, 
  296.    6,  6,  6,  6,  6,  6,  6,  6,  6, 
  297.    8,  8,  8,  8,  8,  8,  8,  8,  8 };
  298.  
  299. #define RookAdvanceSR RookAdvanceSS
  300. #define RookAdvanceRR RookAdvanceRS
  301.  
  302. /* King positional bonus inopening stage (STATIC ROOK vs. STATIC ROOK) */
  303. static const short KingAdvanceSS[NO_SQUARES] =
  304. {  0, -4, 10,  0, -6, -8,-10,-12,-12,
  305.   -2,  4,  6, -6, -8, -8,-10,-12,-12,
  306.   -6, -6, -6, -8, -8,-10,-11,-12,-12,
  307.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  308.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  309.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  310.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  311.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  312.  -12,-12,-12,-12,-12,-12,-12,-12,-12 };
  313.  
  314. /* King positional bonus inopening stage (STATIC ROOK vs. RANGING ROOK) */
  315. static const short KingAdvanceSR[NO_SQUARES] =
  316. {  5, -4, -4, -4, -6, -8,-10,-12,-12,
  317.   -2,  4, 10,  6, -8, -8,-10,-12,-12,
  318.   -6, -6, -6, -8, -8,-10,-11,-12,-12,
  319.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  320.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  321.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  322.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  323.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  324.  -12,-12,-12,-12,-12,-12,-12,-12,-12 };
  325.  
  326. /* King positional bonus inopening stage (RANGING ROOK vs. STATIC ROOK) */
  327. static const short KingAdvanceRS[NO_SQUARES] =
  328. {-12,-12, -8, -6, -4, -8,-10,-12,-12,
  329.  -12,-12, -8, -6, -8, 12, 16, 20, -8,
  330.  -12,-12, -6, -8, -8,-10,  0,  0, -4,
  331.  -12,-12,-12,-12,-12,-12,  0,  0,-12,
  332.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  333.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  334.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  335.  -12,-12,-12,-12,-12,-12,-12,-12,-12,
  336.  -12,-12,-12,-12,-12,-12,-12,-12,-12 };
  337.                                   
  338. #define KingAdvanceRR KingAdvanceRS
  339.                      
  340.  
  341.  
  342. static short Kfield[2][NO_SQUARES];
  343.  
  344. char GameType[2] = { UNKNOWN, UNKNOWN };
  345.  
  346. #ifdef USE_PATTERN
  347. OpeningPattern *attack_pattern[2], *castle_pattern[2];
  348. #endif
  349.  
  350. short Mpawn[2][NO_SQUARES]; 
  351. short Msilver[2][NO_SQUARES]; 
  352. short Mgold[2][NO_SQUARES]; 
  353.  
  354. static short *Mlance[2]; 
  355. static short *Mknight[2]; 
  356. static short *Mbishop[2]; 
  357. static short *Mrook[2]; 
  358.  
  359. static short Mking[2][NO_SQUARES];
  360.  
  361. static short c1, c2;
  362. static small_short *PC1, *PC2;
  363.  
  364. static long *atk1, *atk2;
  365.  
  366. static long int atak[2][NO_SQUARES];
  367. static short R2NDCOL, EDRNK2B, PWEAKH, PADVNCM, PAWNSHIELD;
  368. static short NADVNCM, SADVNCM, GADVNCM;
  369. static short PMBLTY, BDCLOSED, PSTRONG, P2STRONG;
  370.  
  371. static short PawnBonus, BishopBonus, RookBonus;
  372. static short KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
  373. static short RHOPN, RHOPNX, BHCLSD, BHCLSDX, KHOPN, KHOPNX, KSFTY;
  374.  
  375. static short LHOPN, LHOPNX, LPROTECT, NDNGR, LDNGR;
  376. static short SBEFOREG, BXCHG;
  377. static short LXRAY, BRXRAY;
  378. static short KINGED, KINGOD, PROMD;
  379.  
  380. static short KCASTLD, KMOVD, KADVNCM, OPENOK, OPENWRONG;
  381. static short ATAKD, HUNGP, HUNGX, PINVAL;
  382.  
  383. #ifdef USE_PATTERN
  384. static short PATTACK, PCASTLE;
  385. #endif
  386.  
  387.  
  388. short emtl[2];
  389. short pscore[2];
  390. short tmtl;
  391.  
  392.  
  393.  
  394. #if defined DEBUG8 || defined DEBUG_EVAL
  395.                                                
  396.  
  397. void
  398. debug_position (FILE *D)
  399.   short r, c, l, side, piece;
  400.  
  401.   fprintf (D, "\n current board is\n\n");
  402.   for (piece = pawn; piece <= king; piece++)
  403.     if (c = Captured[white][piece]) 
  404.       fprintf(D, "%i%c ",c,pxx[piece]);
  405.   fprintf (D, "\n");
  406.   for (c = 0; c < NO_COLS; c++)
  407.     fprintf (D, " %d", PawnCnt[white][c]); 
  408.   fprintf (D, "\n\n");
  409.   for (r = (NO_ROWS-1); r >= 0; r--)
  410.     {
  411.     for (c = 0; c < NO_COLS; c++)
  412.         {
  413.           l = locn (r, c);
  414.           if (color[l] == neutral)
  415.         fprintf (D, " -");
  416.           else if (color[l] == black)
  417.         fprintf (D, " %c", qxx[board[l]]);
  418.           else
  419.         fprintf (D, " %c", pxx[board[l]]);
  420.         }
  421.     fprintf (D, "\n");
  422.     }
  423.   fprintf (D, "\n");
  424.   for (c = 0; c < NO_COLS; c++)
  425.     fprintf (D, " %d", PawnCnt[black][c]); 
  426.   fprintf (D, "\n");
  427.   for (piece = pawn; piece <= king; piece++)
  428.     if (c = Captured[black][piece]) 
  429.       fprintf(D, "%i%c ",c,pxx[piece]);
  430.   fprintf(D, "\n");
  431. }                                      
  432.  
  433. void
  434. debug_svalue (FILE *D)
  435.   short r, c;
  436.  
  437.   for (r = (NO_ROWS-1); r >= 0; r--)
  438.     {
  439.     for (c = 0; c < NO_COLS; c++)
  440.         {
  441.           short sq = (r * NO_COLS) + c;
  442.           fprintf(D,"%5d",svalue[sq]);
  443.         }
  444.     fprintf (D, "\n");
  445.     }
  446.   fprintf (D, "\n");
  447. }                                      
  448.  
  449. void
  450. debug_table (FILE *D, short *table)
  451.   short r, c;
  452.  
  453.   for (r = (NO_ROWS-1); r >= 0; r--)
  454.     {
  455.     for (c = 0; c < NO_COLS; c++)
  456.         {
  457.           short sq = (r * NO_COLS) + c;
  458.           fprintf(D,"%5d",table[sq]);
  459.         }
  460.     fprintf (D, "\n");
  461.     }
  462.   fprintf (D, "\n");
  463. }                                      
  464.  
  465. void
  466. debug_ataks (FILE *D)
  467. {              
  468.   short side;
  469.   for (side = black; side <= white; side++)
  470.     {                 
  471.     short l,c,i;         
  472.     long *atk = atak[side];
  473.     fprintf(D, "\n");
  474.     for (l = NO_ROWS-1; l >= 0; l--) {
  475.       for (c = 0; c < NO_COLS; c++) {
  476.         short sq = (l * NO_COLS) + c;
  477.         long  v = atk[sq];
  478.         short n = (short)(v & CNT_MASK);
  479.         char s[20];
  480.         fprintf(D,"%2d",n);
  481.         strcpy(s,"");
  482.         if ( v & ctlP  ) strcat(s,"P"); 
  483.         if ( v & ctlPp ) strcat(s,"+P");
  484.         if ( v & ctlL  ) strcat(s,"L"); 
  485.         if ( v & ctlLp ) strcat(s,"+L"); 
  486.         if ( v & ctlN  ) strcat(s,"N"); 
  487.         if ( v & ctlNp ) strcat(s,"+N"); 
  488.         if ( v & ctlS  ) strcat(s,"S"); 
  489.         if ( v & ctlSp ) strcat(s,"+S"); 
  490.         if ( v & ctlG  ) strcat(s,"G"); 
  491.         if ( v & ctlB  ) strcat(s,"B"); 
  492.         if ( v & ctlBp ) strcat(s,"+B"); 
  493.         if ( v & ctlR  ) strcat(s,"R"); 
  494.         if ( v & ctlRp ) strcat(s,"+R"); 
  495.         if ( v & ctlK  ) strcat(s,"K");
  496.         fprintf(D,s);
  497.         for (i = strlen(s); i < 5; i++)
  498.         fprintf(D," ");
  499.         fprintf(D," "); 
  500.       }                              
  501.       fprintf(D,"\n");
  502.     }
  503.     fprintf(D, "\n");
  504.     }
  505. }
  506.  
  507. #endif
  508.  
  509.  
  510.  
  511.  
  512. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  513.  
  514. /*
  515.  * Inputs are:
  516.  * pmtl[side] - value of pawns
  517.  * mtl[side]  - value of all material
  518.  * emtl[side] - value of all material - value of pawns - value of king
  519.  * hung[side] - count of hung pieces
  520.  * Tscore[ply] - search tree score for ply
  521.  * ply
  522.  * Pscore[ply] - positional score for ply ply
  523.  * INCscore    - bonus score or penalty for certain moves
  524.  * slk - single lone king flag
  525.  * Sdepth - search goal depth
  526.  * xwndw - evaluation window about alpha/beta
  527.  * EWNDW - second evaluation window about alpha/beta
  528.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  529.  */
  530.  
  531.  
  532.  
  533. int
  534. evaluate (register short int side,
  535.       register short int ply,
  536.       register short int alpha,
  537.       register short int beta,
  538.       short int INCscore,
  539.       short int *InChk)    /* output Check flag */
  540.  
  541. /*
  542.  * Compute an estimate of the score by adding the positional score from the
  543.  * previous ply to the material difference. If this score falls inside a
  544.  * window which is 180 points wider than the alpha-beta window (or within a
  545.  * 50 point window during quiescence search) call ScorePosition() to
  546.  * determine a score, otherwise return the estimated score. 
  547.  */
  548.  
  549. {
  550.     register short evflag, xside;
  551.     register short int slk;
  552.     short s, sq;
  553.     int HEVAL = false;
  554.  
  555.     xside = side ^ 1;
  556.     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] + INCscore;
  557.     hung[black] = hung[white] = 0;
  558.           /* should we use the estimete or score the position */
  559.     if ((ply <= Sdepth ||
  560. #ifdef CACHE
  561.         (HEVAL = CheckEETable (side)) ||
  562. #endif
  563.     ((ply == Sdepth + 1 || ply == (Sdepth + 2)) && (s > (alpha - xwndw) && s < (beta + xwndw))) ||
  564.     (ply > (Sdepth + 2) && s >= (alpha - EWNDW) && s <= (beta + EWNDW))))
  565.       {
  566.       /* score the position */
  567.       ataks (side, atak[side]);
  568. #ifdef CHECKPIECELIST
  569.       if ( board[PieceList[xside][0]] != king )
  570.         {
  571.           printf("illegal xside PieceList\n");
  572.           exit(1);
  573.         }    
  574. #endif           
  575. #if ATAKSCROSSCHECK 
  576.       { int b1, b2;
  577.             sq = PieceList[xside][0];
  578.             b1 = SqAtakd (sq, side);
  579.         b2 = Anyatak (side, sq);
  580.             if ( b1 != b2 ) {
  581.               printf("SqAtakd %d != Anyatak %d for square %d\n",b1,b2,sq);
  582.               exit(1);
  583.             } else {
  584.               if ( b1 )
  585.             return ((SCORE_LIMIT+1001) - ply); 
  586.             }
  587.           }
  588. #else
  589.       if ( board[sq = PieceList[xside][0]] == king )
  590.       if (Anyatak (side, sq))
  591.           return ((SCORE_LIMIT+1001) - ply);
  592. #endif
  593.       ataks (xside, atak[xside]);
  594. #ifdef CHECKPIECELIST
  595.       if ( board[PieceList[side][0]] != king )
  596.         {
  597.           printf("illegal side PieceList\n");
  598.           exit(1);
  599.         }    
  600. #endif           
  601. #if ATAKSCROSSCHECK 
  602.       { int b1, b2;
  603.             sq = PieceList[side][0];
  604.             b1 = SqAtakd (sq, xside);
  605.         b2 = Anyatak (xside, sq);
  606.             if ( b1 != b2 ) {
  607.               printf("SqAtakd %d != Anyatak %d for square %d\n",b1,b2,sq);
  608.               exit(1);
  609.             } else {
  610.               *InChk = b1;
  611.             }
  612.           }
  613. #else
  614.       if ( board[sq = PieceList[side][0]] == king )
  615.         *InChk = Anyatak (xside, sq);
  616.       else
  617.         *InChk = false;
  618. #endif
  619. #if !defined BAREBONES
  620.       EvalNodes++;
  621. #endif         
  622.       if ( flag.tsume )
  623.         s = urand () % 50;
  624.       else  
  625.         s = ScorePosition (side);
  626.       }
  627.     else
  628.       {
  629.       /* use the estimate but look at check and slk */
  630.       short sq;
  631.       sq = PieceList[xside][0];
  632. #if CHECKPIECELIST 
  633.       if ( board[sq] != king )
  634.         {
  635.           printf("illegal xside 2 PieceList\n");
  636.           exit(1);
  637.         }
  638. #endif        
  639. #if ATAKSCROSSCHECK 
  640.       { int b1, b2;
  641.         ataks (side, atak[side]);
  642.             b1 = SqAtakd (sq, side);
  643.         b2 = Anyatak (side, sq);
  644.             if ( b1 != b2 ) {
  645.               printf("SqAtakd %d != Anyatak %d for square %d\n",b1,b2,sq);
  646.               exit(1);
  647.             } else {
  648.               if ( b1 )
  649.             return ((SCORE_LIMIT+1001) - ply); 
  650.             }
  651.           }
  652. #else
  653.       if ( board[sq] == king )
  654.       if ( SqAtakd (sq, side) )
  655.           return ((SCORE_LIMIT+1001) - ply);
  656. #endif
  657.       sq = PieceList[side][0];
  658. #if CHECKPIECELIST 
  659.       if ( board[sq] != king )
  660.         {
  661.           printf("illegal side 2 PieceList\n");
  662.           exit(1);
  663.         }
  664. #endif
  665. #if ATAKSCROSSCHECK 
  666.       { int b1, b2;
  667.         ataks (xside, atak[xside]);
  668.             b1 = SqAtakd (sq, xside);
  669.         b2 = Anyatak (xside, sq);
  670.             if ( b1 != b2 ) {
  671.               printf("SqAtakd %d != Anyatak %d for xsquare %d\n",b1,b2,sq);
  672.               exit(1);
  673.             } else {
  674.               *InChk = b1;
  675.             }
  676.           }
  677. #else
  678.       if ( board[sq] == king )
  679.         *InChk = SqAtakd (sq, xside); 
  680.       else
  681.         *InChk = false;
  682. #endif
  683.       }
  684.  
  685.     Pscore[ply] = s + (mtl[xside] - mtl[side]);
  686.     ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] : 0);
  687.     return (s);
  688. }
  689.  
  690. inline
  691. int
  692. BRLscan (register short int sq, short int *mob)
  693.  
  694. /*
  695.  * Find (promoted) Bishop, (promoted) Rook, and Lance mobility, XRAY attacks, and pins. 
  696.  * Let BRL be the bishop, rook, or lance.
  697.  * Let P be the first piece (no king and no pawn) in a direction and let Q be the second
  698.  * piece in the same direction. If Q is an unprotected opponent's piece with 
  699.  * bigger relative value than BRL, there is a pin if P is an opponent's piece and
  700.  * there is an XRAY attack if P is an own piece.
  701.  * Increment the hung[] array if a pin is found.
  702.  */
  703. {
  704.     register unsigned char *ppos, *pdir;
  705.     register short s, mobx;
  706.     register short u, pin, ptyp;
  707.     short piece, *Kf, rvalue;
  708.     mobx = s = 0;
  709.     Kf = Kfield[c1];
  710.     piece = board[sq];
  711.  
  712.     rvalue = relative_value[piece];
  713.     ptyp = ptype[c1][unpromoted[piece]];
  714.     ppos = (*nextpos[ptyp])[sq];
  715.     pdir = (*nextdir[ptyp])[sq];
  716.  
  717.     u = ppos[sq];                         
  718.     pin = -1;            /* start new direction */
  719.     do
  720.       {
  721.       s += Kf[u];
  722. #ifdef DEBUG_EVAL
  723.       if ( debug_eval && Kf[u] != 0 )
  724.         fprintf(debug_eval_file,"add %d for controlling square near enemy king\n",Kf[u]);
  725. #endif
  726.       if (color[u] == neutral)
  727.         {
  728.         mobx++;
  729.         if (ppos[u] == pdir[u])
  730.             pin = -1;    /* oops new direction */
  731.         u = ppos[u];
  732.         }
  733.       else 
  734.         {   /* there is a piece in current direction */
  735.         if (pin < 0)
  736.             {   /* it's the first piece in the current direction */
  737.             if (piece == lance && color[u] == c1 )
  738.               {
  739.                   s += LPROTECT;
  740. #ifdef DEBUG_EVAL
  741.                   if ( debug_eval )
  742.                 fprintf(debug_eval_file,"adding %d for lance protection\n",LPROTECT);
  743. #endif
  744.               }
  745.             else if ( piece == bishop && board[u] == pawn )
  746.               {
  747.                   if ( color[u] == c1 )
  748.                 {
  749.                   s += 2*BHCLSD; 
  750. #ifdef DEBUG_EVAL
  751.                   if (debug_eval )
  752.                     fprintf(debug_eval_file,"add %d for own pawn in bishops direction\n",2*BHCLSD);
  753. #endif
  754.                 }
  755.                   else
  756.                 {
  757.                   s += 2*BHCLSDX;
  758. #ifdef DEBUG_EVAL
  759.                   if (debug_eval )
  760.                     fprintf(debug_eval_file,"add %d for opponents pawn in bishops direction\n",2*BHCLSDX);
  761. #endif
  762.                 }
  763.               }
  764.             if (board[u] == pawn || board[u] == king)
  765.                 u = pdir[u];
  766.             else
  767.               {
  768.                   if (ppos[u] != pdir[u])
  769.                   pin = u;    /* not on the edge and on to find a pin */
  770.                   u = ppos[u];
  771.               }
  772.             }
  773.         else
  774.             {
  775.             /* it's the second piece in the current direction */
  776.             if ( piece == bishop && board[u] == pawn )
  777.               {
  778.                   if ( color[u] == c1 )
  779.                 {
  780.                   s += BHCLSD; 
  781. #ifdef DEBUG_EVAL
  782.                   if (debug_eval )
  783.                     fprintf(debug_eval_file,"add %d for own pawn in bishops direction\n",BHCLSD);
  784. #endif
  785.                 }
  786.                   else
  787.                 {
  788.                   s += BHCLSDX;
  789. #ifdef DEBUG_EVAL
  790.                   if (debug_eval )
  791.                     fprintf(debug_eval_file,"add %d for opponents pawn in bishops direction\n",BHCLSDX);
  792. #endif
  793.                 }
  794.               }
  795.             if ((color[u] == c2) && 
  796.                         (relative_value[board[u]] > rvalue || atk2[u] == 0))
  797.               {
  798.                   if (color[pin] == c2)
  799.                 {
  800.                     s += PINVAL;
  801. #ifdef DEBUG_EVAL
  802.                     if ( debug_eval )
  803.                       fprintf(debug_eval_file,"adding %d for pin\n",PINVAL);
  804. #endif
  805.                     if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  806.                     ++hung[c2];
  807.                 }
  808.                   else
  809.                 if ( piece == lance ) {
  810.                   s += LXRAY;
  811. #ifdef DEBUG_EVAL
  812.                   if ( debug_eval )
  813.                     fprintf(debug_eval_file,"lance xray: %d\n",LXRAY);
  814. #endif
  815.                 } else {
  816.                   s += BRXRAY; 
  817. #ifdef DEBUG_EVAL
  818.                   if ( debug_eval )
  819.                     fprintf(debug_eval_file,"bishop/rook xray: %d\n",BRXRAY);
  820. #endif
  821.                 }
  822.               }   
  823.             pin = -1;    /* new direction */
  824.             u = pdir[u];
  825.             }
  826.         }
  827.       }
  828.     while (u != sq);
  829.     *mob = mobx;
  830.     return s;
  831. }
  832.  
  833. inline
  834. short int
  835. KingScan (register short int sq)
  836.  
  837. /*
  838.  * Assign penalties if king can be threatened by checks, if squares near the
  839.  * king are controlled by the enemy (especially the queen), or if there are
  840.  * no pawns near the king. The following must be true: board[sq] == king c1
  841.  * == color[sq] c2 == otherside[c1]
  842.  */
  843.  
  844.  
  845. #define ScoreThreat \
  846.     if (color[u] != c2)\
  847.       if (atk1[u] == 0 || (atk2[u] & CNT_MASK) > 1) ++cnt;\
  848.       else s -= 3
  849.  
  850.  
  851. {
  852.     register short cnt;
  853.     register unsigned char *ppos, *pdir;
  854.     register short int s;
  855.     register short u, ptyp;
  856.     short int ok;
  857.  
  858.     s = 0;
  859.     cnt = 0;
  860.     { short p;
  861.       for ( p = pawn; p < king; p++ )
  862.     if ( HasPiece[c2][p] )
  863.           { short ptyp = ptype[c2][p];
  864.         ppos = (*nextpos[ptyp])[sq];
  865.         pdir = (*nextdir[ptyp])[sq];
  866.         u = ppos[sq];
  867.         do
  868.           {
  869.         if (atk2[u] & control[p])
  870.             ScoreThreat;
  871.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  872.           }
  873.         while (u != sq);
  874.           }
  875.     }
  876.     s += (KSFTY * KTHRT[cnt]);
  877.  
  878.     cnt = 0;
  879.     ok = false;
  880.     ptyp = ptype[black][king];
  881.     pdir = (*nextpos[ptyp])[sq];
  882.     u = pdir[sq];
  883.     do
  884.       {
  885.       if (board[u] == pawn)
  886.           ok = true;
  887.       if (atk2[u] > atk1[u])
  888.         {
  889.         ++cnt;
  890.         }
  891.       u = pdir[u];
  892.       }
  893.     while (u != sq);
  894.     if (!ok)
  895.     s -= KSFTY;
  896.     if (cnt > 1)
  897.     s -= KSFTY;
  898.     return (s);
  899. }
  900.  
  901. inline
  902. int
  903. trapped (register short int sq)
  904.  
  905. /*
  906.  * See if the attacked piece has unattacked squares to move to. The following
  907.  * must be true: c1 == color[sq] c2 == otherside[c1]
  908.  */
  909.  
  910. {
  911.     register short u, ptyp;
  912.     register unsigned char *ppos, *pdir;
  913.     register short int piece;
  914.  
  915.     piece = board[sq];
  916.     ptyp = ptype[c1][piece];
  917.     ppos = (*nextpos[ptyp])[sq];
  918.     pdir = (*nextdir[ptyp])[sq];
  919.       {
  920.       short rvalue = relative_value[piece];
  921.       u = ppos[sq];
  922.       do
  923.         {   
  924.         if (color[u] != c1)
  925.             if (atk2[u] == 0 || relative_value[board[u]] >= rvalue)
  926.               return (false);
  927.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  928.         }
  929.       while (u != sq);
  930.       }
  931. #ifdef DEBUG_EVAL
  932.     if ( debug_eval )
  933.       fprintf(debug_eval_file,"piece is trapped\n");
  934. #endif                             
  935.     return (true);
  936. }
  937.  
  938.  
  939.                                    
  940. #define mirrored(sq) (NO_SQUARES-1-sq)
  941. #define csquare(side,sq) ((side==black)?sq:mirrored(sq))
  942. #define crow(side,sq) row(csquare(side,sq))
  943. #define ccolumn(side,sq) column(csquare(side,sq))
  944.  
  945.  
  946. inline
  947. static short on_csquare(short side,short piece,short square)
  948. { short sq;
  949.   return(board[sq=csquare(side,square)]==piece && color[sq]==side);
  950. }
  951.     
  952. inline
  953. static short on_column(short side,short piece,short c)
  954. { short sq;
  955.   for (sq = c; sq < NO_SQUARES; sq+=9)
  956.     if (on_csquare(side,piece,sq))
  957.       return(true);
  958.   return(false);
  959. }
  960.  
  961. #define empty_square(side,square) (board[csquare(side,square)]==no_piece)
  962.  
  963. inline
  964. static short on_left_side(short side,short piece)
  965. { short c;
  966.   for (c=0; c<4; c++)
  967.     if (on_column(side,piece,c))
  968.       return(true);
  969.   return(false);
  970. }
  971.  
  972. inline
  973. static short on_right_side(short side,short piece)
  974. { short c;
  975.   for (c=5; c<NO_COLS; c++)
  976.     if (on_column(side,piece,c))
  977.       return(true);
  978.   return(false);
  979. }
  980.  
  981.  
  982. /* Distance bonus */
  983.  
  984. inline
  985. static
  986. short AddEnemyKingDistanceBonus (short sq)
  987. { short s = 0;
  988.   /* near enemy king */
  989.   if ( !in_opening_stage || behind_in_material[c1] )
  990.   if ( distance(sq,OwnKing) > 2 )
  991.     s = EnemyKingDistanceBonus[distance(sq,EnemyKing)];
  992.   return(s);
  993. }
  994.  
  995. inline
  996. static
  997. short AddOwnKingDistanceBonus (short sq)
  998. { short s = 0;
  999.   /* near own king */
  1000.   if ( !in_opening_stage || behind_in_material[c1] )
  1001.     s = OwnKingDistanceBonus[distance(sq,OwnKing)];
  1002.   return(s);
  1003. }
  1004.  
  1005. inline
  1006. static
  1007. short AddPromotionZoneDistanceBonus (short sq)
  1008. { short s = 0;
  1009.   /* near promotion zone */
  1010.   if ( !in_opening_stage )
  1011.     s = PromotionZoneDistanceBonus[crow(c1,sq)];
  1012.   return(s);
  1013. }
  1014.  
  1015.  
  1016. static inline int
  1017. PawnValue (register short int sq, short int side)
  1018. /*
  1019.  * Calculate the positional value for a pawn on 'sq'.
  1020.  */
  1021.  
  1022. {
  1023.     register short s;
  1024.     long a1, a2;
  1025.  
  1026.     s = Mpawn[c1][csquare(c1,sq)];
  1027.  
  1028. #ifdef DEBUG_EVAL
  1029.     if ( debug_eval )
  1030.       fprintf(debug_eval_file,"inital value [%d] for pawn on %c%c: %d\n",
  1031.         csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
  1032. #endif
  1033.  
  1034.     s += PROMD * AddPromotionZoneDistanceBonus(sq);
  1035.  
  1036.     /* pawn mobility */
  1037.     {
  1038.     short u, ptyp;
  1039.     register unsigned char *pdir;
  1040.     ptyp = ptype[c1][pawn];
  1041.     pdir = (*nextdir[ptyp])[sq];
  1042.     u = pdir[sq];
  1043.     if ( u != sq )
  1044.       if ( color[u] == neutral ) {
  1045.             s += PMBLTY;
  1046. #ifdef DEBUG_EVAL
  1047.         if ( debug_eval )
  1048.               fprintf(debug_eval_file,"adding %d for mobility\n", PMBLTY);
  1049. #endif       
  1050.       }
  1051.     }
  1052.     
  1053.     a1 = atk1[sq];
  1054.     a2 = atk2[sq];
  1055.  
  1056.     if (a2 > 0)
  1057.       {
  1058.       if (a1 == 0 || a2 > ctlP + 1)
  1059.         {
  1060.         s += HUNGP;
  1061. #ifdef DEBUG_EVAL
  1062.         if ( debug_eval )
  1063.                   fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
  1064. #endif       
  1065.         if (trapped (sq)) {
  1066.             hung[c1] += 2;
  1067.         }
  1068.         hung[c1]++;
  1069.         }
  1070.       else if (a2 > a1) {
  1071.           s += ATAKD;   
  1072. #ifdef DEBUG_EVAL     
  1073.           if ( debug_eval )
  1074.                 fprintf(debug_eval_file,"adding %d for atacked piece\n",ATAKD);
  1075. #endif                             
  1076.       }
  1077.       }          
  1078.  
  1079.     if ( a1 > 0 ) {
  1080.       s += (a1 & CNT_MASK);
  1081. #ifdef DEBUG_EVAL
  1082.       if ( debug_eval )
  1083.         fprintf(debug_eval_file,"adding %d for protected piece\n",(a1 & CNT_MASK));
  1084. #endif                             
  1085.     }
  1086.  
  1087.     if ( sq == csquare(c1,20) ) {
  1088.       s += BDCLOSED;
  1089. #ifdef DEBUG_EVAL
  1090.       if ( debug_eval )
  1091.         fprintf(debug_eval_file,"adding %d for closed bishops diagonal\n",BDCLOSED);
  1092. #endif         
  1093.     }                    
  1094.  
  1095.     if ( (a1 & ((ctlR | ctlRp) | ctlL)) ) {
  1096.       s += PSTRONG;
  1097. #ifdef DEBUG_EVAL
  1098.       if ( debug_eval )
  1099.         fprintf(debug_eval_file,"adding %d for rook/lance-supported pawn\n", PSTRONG);
  1100. #endif
  1101.     }         
  1102.  
  1103.     if ( in_opening_stage )
  1104.       if ( crow(c1,sq) == 2 ) /* pawn on 3d rank */
  1105.         if ( Mvboard[(c1==black)?(sq+36):(sq-36)] )
  1106.           {  /* opposing pawn has been moved (even column == (sq & 1)) */
  1107.          s -= (sq & 1) ? PMBLTY : (3*PMBLTY)/2;   
  1108. #ifdef DEBUG_EVAL
  1109.          if ( debug_eval )
  1110.                fprintf(debug_eval_file,"adding %d for opposing pawn pushed\n",
  1111.                    -((sq & 1) ? PMBLTY : (3*PMBLTY)/2));
  1112. #endif         
  1113.           }
  1114.       
  1115.     if ( sq == csquare(c1,43) )
  1116.       {  
  1117.         if ( (atk2[csquare(c1,52)] & CNT_MASK) < 2 ) {
  1118.              s += P2STRONG;
  1119. #ifdef DEBUG_EVAL
  1120.          if ( debug_eval )
  1121.                fprintf(debug_eval_file,"adding %d for attacking pawn on 2nd col\n",
  1122.                    P2STRONG);
  1123. #endif         
  1124.           }
  1125.       }
  1126.  
  1127.     return (s);
  1128. }
  1129.  
  1130.  
  1131. static inline int
  1132. LanceValue (register short int sq, short int side)
  1133. /*
  1134.  * Calculate the positional value for a lance on 'sq'.
  1135.  */
  1136.  
  1137. {
  1138.     register short s;
  1139.     register short fyle;
  1140.     short mob;
  1141.     long a1, a2;
  1142.     short checked_trapped = false;
  1143.  
  1144.     s = Mlance[c1][csquare(c1,sq)];
  1145.     
  1146. #ifdef DEBUG_EVAL
  1147.     if ( debug_eval )
  1148.       fprintf(debug_eval_file,"inital value [%d] for lance on %c%c: %d\n",
  1149.         csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
  1150. #endif
  1151.  
  1152.     s += KINGOD * AddOwnKingDistanceBonus(sq);
  1153.  
  1154.     s += BRLscan (sq, &mob);
  1155.     s += LMBLTY[mob];
  1156.  
  1157.     fyle = column (sq);
  1158.  
  1159.     if (PC1[fyle] == 0)
  1160.       {
  1161.     s += LHOPN;
  1162. #ifdef DEBUG_EVAL
  1163.     if ( debug_eval )
  1164.       fprintf(debug_eval_file,"adding %d for no own pawn on lance file\n",LHOPN);
  1165. #endif
  1166.       }
  1167.     if (PC2[fyle] == 0)
  1168.       {
  1169.     s += LHOPNX;
  1170. #ifdef DEBUG_EVAL
  1171.     if ( debug_eval )
  1172.       fprintf(debug_eval_file,"adding %d for no opponents pawn on lance file\n",LHOPNX);
  1173. #endif
  1174.       }
  1175.  
  1176.     a2 = atk2[sq];
  1177.     a1 = atk1[sq];
  1178.  
  1179.     if (a2 > 0)
  1180.       {
  1181.       if (a1 == 0 || a2 > ctlL + 1)
  1182.         {
  1183.         s += HUNGP;
  1184. #ifdef DEBUG_EVAL
  1185.         if ( debug_eval )
  1186.                   fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
  1187. #endif              
  1188.         if (trapped (sq))
  1189.             hung[c1] += 2;
  1190.         hung[c1]++;
  1191.         }
  1192.       else if (a2 >= ctlL || a1 < ctlP)
  1193.         {
  1194.           s += ATAKD;
  1195. #ifdef DEBUG_EVAL     
  1196.           if ( debug_eval )
  1197.                 fprintf(debug_eval_file,"adding %d for atacked piece\n",ATAKD);
  1198. #endif       
  1199.         }                      
  1200.       }
  1201.  
  1202.     if ( !checked_trapped && crow(c1,sq) > 2 )
  1203.       {          
  1204.     if (trapped (sq))
  1205.       {
  1206.         s += LDNGR;
  1207. #ifdef DEBUG_EVAL     
  1208.         if ( debug_eval )
  1209.                 fprintf(debug_eval_file,"adding %d for lance in danger\n",LDNGR);
  1210. #endif                             
  1211.       }
  1212.     else
  1213.       {
  1214.         s += LDNGR / 4;
  1215. #ifdef DEBUG_EVAL     
  1216.         if ( debug_eval )
  1217.                 fprintf(debug_eval_file,"adding %d for lance in danger\n",LDNGR / 4);
  1218. #endif                             
  1219.       }
  1220.       }
  1221.  
  1222.     if ( a1 > 0 ) {
  1223.       s += (a1 & CNT_MASK);
  1224. #ifdef DEBUG_EVAL
  1225.       if ( debug_eval )
  1226.         fprintf(debug_eval_file,"adding %d for protected piece\n",(a1 & CNT_MASK));
  1227. #endif             
  1228.     }                
  1229.  
  1230.     return (s);
  1231. }
  1232.  
  1233. static inline int
  1234. KnightValue (register short int sq, short int side)
  1235. /*
  1236.  * Calculate the positional value for a knight on 'sq'.
  1237.  */
  1238.  
  1239. {
  1240.     register short s;
  1241.     long a1, a2;    
  1242.     short checked_trapped = false;
  1243.  
  1244.     s = Mknight[c1][csquare(c1,sq)];
  1245.  
  1246. #ifdef DEBUG_EVAL
  1247.     if ( debug_eval )
  1248.       fprintf(debug_eval_file,"inital value [%d] for knight on %c%c: %d\n",
  1249.         csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
  1250. #endif
  1251.  
  1252.     s += PROMD * AddPromotionZoneDistanceBonus(sq);
  1253.     s += KINGOD * AddOwnKingDistanceBonus(sq);
  1254.  
  1255.     a2 = atk2[sq];
  1256.     a1 = atk1[sq];
  1257.  
  1258.     if (a2 > 0)
  1259.       {
  1260.       if (a1 == 0 || a2 > ctlN + 1)
  1261.         {
  1262.         s += HUNGP;
  1263. #ifdef DEBUG_EVAL
  1264.         if ( debug_eval )
  1265.                   fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
  1266. #endif              
  1267.             checked_trapped = true;
  1268.         if (trapped (sq))
  1269.             hung[c1] += 2;
  1270.         hung[c1]++;
  1271.         }
  1272.       else if (a2 >= ctlN || a1 < ctlP)
  1273.         {
  1274.           s += ATAKD;
  1275. #ifdef DEBUG_EVAL     
  1276.           if ( debug_eval )
  1277.                 fprintf(debug_eval_file,"adding %d for atacked piece\n",ATAKD);
  1278. #endif                             
  1279.         }
  1280.       }         
  1281.  
  1282.     if ( !checked_trapped && crow(c1,sq) > 2 )
  1283.       {          
  1284.     if (trapped (sq))
  1285.       {
  1286.         s += NDNGR;
  1287. #ifdef DEBUG_EVAL     
  1288.         if ( debug_eval )
  1289.                 fprintf(debug_eval_file,"adding %d for knight in danger\n",NDNGR);
  1290. #endif                             
  1291.       }
  1292.     else
  1293.       {
  1294.         s += NDNGR / 4;
  1295. #ifdef DEBUG_EVAL     
  1296.         if ( debug_eval )
  1297.                 fprintf(debug_eval_file,"adding %d for knight in danger\n",NDNGR / 4);
  1298. #endif                             
  1299.       }
  1300.       }
  1301.  
  1302.     if ( a1 > 0 ) {
  1303.       s += (a1 & CNT_MASK);
  1304. #ifdef DEBUG_EVAL
  1305.       if ( debug_eval )
  1306.         fprintf(debug_eval_file,"adding %d for protected piece\n",(a1 & CNT_MASK));
  1307. #endif             
  1308.     }
  1309.                 
  1310.     return (s);
  1311. }
  1312.  
  1313. static inline int
  1314. SilverValue (register short int sq, short int side)
  1315. /*
  1316.  * Calculate the positional value for a silver on 'sq'.
  1317.  */
  1318.  
  1319. {
  1320.     register short s;
  1321.     long a1, a2;
  1322.  
  1323.     s = Msilver[c1][csquare(c1,sq)];
  1324.  
  1325.     s += KINGED * AddEnemyKingDistanceBonus(sq);
  1326.     s += KINGOD * AddOwnKingDistanceBonus(sq);
  1327.  
  1328.     a2 = atk2[sq];
  1329.     a1 = atk1[sq];
  1330.     if (a2 > 0)
  1331.       {
  1332.       if (a1 == 0 || a2 > ctlS + 1)
  1333.         {
  1334.         s += HUNGP;
  1335.         if (trapped (sq))
  1336.             hung[c1] += 2;
  1337.         hung[c1]++;
  1338.         }
  1339.       else if (a2 >= ctlS || a1 < ctlP)
  1340.           s += ATAKD;
  1341.       }
  1342.     if ( a1 > 0 )
  1343.       s += (a1 & CNT_MASK);
  1344.  
  1345.     if ( in_opening_stage && GameType[c1] == STATIC_ROOK )
  1346.     if ( csquare(c1,sq) == 12 )
  1347.       {
  1348.         short csq;
  1349.         if ( board[csq = csquare(c1,20)] == bishop && color[csq] == c1 )
  1350.         {
  1351.           s += 2 * OPENWRONG;
  1352.         }
  1353.           }
  1354.  
  1355.     /* proverb: silver before gold */
  1356.     {
  1357.     short u, ptyp;
  1358.     register unsigned char *pdir;
  1359.     ptyp = ptype[c2][pawn];
  1360.     pdir = (*nextdir[ptyp])[sq];
  1361.     u = pdir[sq];
  1362.     if ( u != sq )
  1363.       if ( color[u] == c1 && board[u] == gold )
  1364.             s += SBEFOREG;
  1365.     }
  1366.     return (s);
  1367. }
  1368.  
  1369. static inline int
  1370. GoldValue (register short int sq, short int side)
  1371. /*
  1372.  * Calculate the positional value for a gold on 'sq'.
  1373.  */
  1374.  
  1375. {
  1376.     register short s;
  1377.     long a1, a2;
  1378.  
  1379.     s = Mgold[c1][csquare(c1,sq)];
  1380.  
  1381.     s += KINGED * AddEnemyKingDistanceBonus(sq);
  1382.     s += KINGOD * AddOwnKingDistanceBonus(sq);
  1383.  
  1384.     a2 = atk2[sq];
  1385.     a1 = atk1[sq];
  1386.     if (a2 > 0)
  1387.       {
  1388.       if (a1 == 0 || a2 > ctlG + 1)
  1389.         {
  1390.         s += HUNGP;
  1391.         if (trapped (sq))
  1392.             hung[c1] += 2;
  1393.         hung[c1]++;
  1394.         }
  1395.       else if (a2 >= ctlG || a1 < ctlP)
  1396.           s += ATAKD;
  1397.       }
  1398.     if ( a1 > 0 )
  1399.       s += (a1 & CNT_MASK);
  1400.     return (s);
  1401. }
  1402.  
  1403. static inline int
  1404. BishopValue (register short int sq, short int side)
  1405. /*
  1406.  * Calculate the positional value for a bishop on 'sq'.
  1407.  */
  1408.  
  1409. {
  1410.     register short s;
  1411.     long a2, a1;
  1412.     short mob;
  1413.  
  1414.     s = Mbishop[c1][csquare(c1,sq)];
  1415.  
  1416. #ifdef DEBUG_EVAL
  1417.     if (debug_eval )
  1418.       fprintf(debug_eval_file,"inital value [%d] for bishop on %c%c: %d\n",
  1419.         csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
  1420. #endif
  1421.  
  1422.     s += BRLscan (sq, &mob);
  1423.     s += BMBLTY[mob];
  1424.  
  1425.     a2 = atk2[sq];
  1426.     if (a2 > 0)
  1427.       {
  1428.       a1 = atk1[sq];
  1429.       if (a1 == 0 || a2 > ctlB + 1)
  1430.         {
  1431.         s += HUNGP;
  1432. #ifdef DEBUG_EVAL
  1433.         if ( debug_eval )
  1434.                   fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
  1435. #endif       
  1436.         if (trapped (sq))
  1437.             hung[c1] += 2;
  1438.         hung[c1]++;
  1439.         }
  1440.       else if (a2 >= ctlB || a1 < ctlP)
  1441.         {
  1442.           s += ATAKD;
  1443. #ifdef DEBUG_EVAL     
  1444.           if ( debug_eval )
  1445.                 fprintf(debug_eval_file,"adding %d for atacked piece\n",ATAKD);
  1446. #endif                                                                         
  1447.         }
  1448.       }                      
  1449.  
  1450.     if ( in_opening_stage )
  1451.       {
  1452.     if ( GameType[c1] == RANGING_ROOK )
  1453.       {
  1454.         /* Bishops diagonal should not be open */
  1455.         if ( !on_csquare(c1,pawn,30) )
  1456.           s += OPENWRONG;
  1457.       }
  1458.     else if ( GameType[c2] == RANGING_ROOK )
  1459.       {
  1460.         /* Bishops diagonal should be open */
  1461.         if ( csquare(c1,sq) == 20 && on_csquare(c1,pawn,30) )
  1462.           s += OPENWRONG;
  1463.       }
  1464.       }     
  1465.   
  1466.     return (s);
  1467. }
  1468.  
  1469. static inline int
  1470. RookValue (register short int sq, short int side)
  1471. /*
  1472.  * Calculate the positional value for a rook on 'sq'.
  1473.  */
  1474.  
  1475. {
  1476.     register short s;
  1477.     register short fyle;
  1478.     long a2, a1;
  1479.     short mob, r, c;
  1480.  
  1481.     s = Mrook[c1][csquare(c1,sq)];
  1482.  
  1483. #ifdef DEBUG_EVAL
  1484.     if (debug_eval )
  1485.       fprintf(debug_eval_file,"inital value [%d] for rook on %c%c: %d\n",
  1486.         csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
  1487. #endif
  1488.  
  1489.     s += BRLscan (sq, &mob);
  1490.     s += RMBLTY[mob];
  1491.  
  1492. #ifdef DEBUG_EVAL
  1493.     if ( debug_eval && (c = RMBLTY[mob]) != 0 ) {
  1494.     s += c;
  1495.     fprintf(debug_eval_file,"adding rook for mobility %d value %d\n",mob,c);
  1496.     }
  1497. #endif
  1498.  
  1499.     fyle = column (sq);
  1500.  
  1501.     if (PC1[fyle] == 0) {
  1502.     s += RHOPN;  /* no own pawn on rook file */
  1503. #ifdef DEBUG_EVAL
  1504.     if ( debug_eval )
  1505.       fprintf(debug_eval_file,"adding %d for no own pawn on rook file\n",RHOPN);
  1506. #endif
  1507.     }
  1508.     if (PC2[fyle] == 0) {
  1509.     s += RHOPNX; /* no enemy pawn on rook file */
  1510. #ifdef DEBUG_EVAL
  1511.     if ( debug_eval )
  1512.       fprintf(debug_eval_file,"adding %d for no enemy pawn on rook file\n",RHOPNX);
  1513. #endif                                               
  1514.     }
  1515.  
  1516.     a2 = atk2[sq];
  1517.     if (a2 > 0)
  1518.       {
  1519.       a1 = atk1[sq];
  1520.       if (a1 == 0 || a2 > ctlR + 1)
  1521.         {
  1522.         s += HUNGP;
  1523. #ifdef DEBUG_EVAL
  1524.         if ( debug_eval )
  1525.                   fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
  1526. #endif       
  1527.         if (trapped (sq)) {
  1528.             hung[c1] += 2; 
  1529.         }
  1530.         hung[c1]++;
  1531.         }
  1532.       else if (a2 >= ctlR || a1 < ctlP) 
  1533.         {
  1534.           s += ATAKD;
  1535. #ifdef DEBUG_EVAL     
  1536.           if ( debug_eval )
  1537.                 fprintf(debug_eval_file,"adding %d for atacked piece\n",ATAKD);
  1538. #endif                                                                         
  1539.         }
  1540.       }
  1541.  
  1542.     if ( in_opening_stage ) {
  1543. #ifdef DEBUG_EVAL
  1544.       short s0 = s;
  1545. #endif
  1546.       if ( GameType[c1] == STATIC_ROOK )
  1547.         {
  1548.       short c = ccolumn(c1,sq);
  1549.       /* Bonus for rook on 8th file */
  1550.           if ( c == 7 ) {
  1551.         s += R2NDCOL;
  1552.       }
  1553.       /* Bonus for rook on right side, malus for rook on left side */
  1554.       c = 4 - c;
  1555.           if ( c < 0 ) {
  1556.         s += c + c + OPENOK;
  1557.       } else if ( c >= 0 ) {
  1558.         s += c + c + OPENWRONG;
  1559.       }
  1560.         }
  1561.       else if ( GameType[c1] == RANGING_ROOK )
  1562.         {
  1563.       /* Bonus for rook on left side and bishops diagonal closed, malus otherwise. */
  1564.           short c;
  1565.       c = 4 - ccolumn(c1,sq);
  1566.           if ( c >= 0 ) {
  1567.         /* Bishops diagonal should not be open */
  1568.         if ( on_csquare(c1,pawn,30) )
  1569.           s += OPENOK;
  1570.         else
  1571.           s += c + c + OPENWRONG;
  1572.           } else if ( c < 0 ) {
  1573.         s += c + c + OPENWRONG;
  1574.         /* Malus for king not on initial square */
  1575.         if ( !on_csquare(side,king,4) ) {
  1576.         s += 4 * OPENWRONG;      
  1577.         }
  1578.       }
  1579.         }
  1580. #ifdef DEBUG_EVAL
  1581.       if ( debug_eval && (s0 != s) )
  1582.       fprintf(debug_eval_file,"adding %d for opening\n",(s-s0));
  1583. #endif
  1584.     }
  1585.  
  1586.     return (s);
  1587. }
  1588.  
  1589. static inline int
  1590. PPawnValue (register short int sq, short int side)
  1591. /*
  1592.  * Calculate the positional value for a promoted pawn on 'sq'.
  1593.  */
  1594.  
  1595. {
  1596.     register short s;
  1597.     long a2, a1;
  1598.  
  1599.     s = 0;
  1600.  
  1601.     s += (KINGED + 2) * AddEnemyKingDistanceBonus(sq);
  1602.  
  1603.     a2 = atk2[sq];
  1604.     if (a2 > 0)
  1605.       {
  1606.       a1 = atk1[sq];
  1607.       if (a1 == 0 || a2 > ctlPp + 1)
  1608.         {
  1609.         s += HUNGP;
  1610.         if (trapped (sq))
  1611.             hung[c1] += 2;
  1612.         hung[c1]++;
  1613.         }
  1614.       else if (a2 >= ctlPp || a1 < ctlP)
  1615.           s += ATAKD;
  1616.       }
  1617.  
  1618.     return (s);
  1619. }
  1620.  
  1621. static inline int
  1622. PLanceValue (register short int sq, short int side)
  1623. /*
  1624.  * Calculate the positional value for a promoted lance on 'sq'.
  1625.  */
  1626.  
  1627. {
  1628.     register short s;
  1629.     long a2, a1;
  1630.  
  1631.     s = 0;
  1632.  
  1633.     s += (KINGED + 1) * AddEnemyKingDistanceBonus(sq);
  1634.  
  1635.     a2 = atk2[sq];
  1636.     if (a2 > 0)
  1637.       {
  1638.       a1 = atk1[sq];
  1639.       if (a1 == 0 || a2 > ctlLp + 1)
  1640.         {
  1641.         s += HUNGP;
  1642.         if (trapped (sq))
  1643.             hung[c1] += 2;
  1644.         hung[c1]++;
  1645.         }
  1646.       else if (a2 >= ctlLp || a1 < ctlP)
  1647.           s += ATAKD;
  1648.       }
  1649.  
  1650.     return (s);
  1651. }
  1652.  
  1653. static inline int
  1654. PKnightValue (register short int sq, short int side)
  1655. /*
  1656.  * Calculate the positional value for a promoted knight on 'sq'.
  1657.  */
  1658.  
  1659. {
  1660.     register short s;
  1661.     long a2, a1;
  1662.  
  1663.     s = 0;
  1664.  
  1665.     s += (KINGED + 1 ) * AddEnemyKingDistanceBonus(sq);
  1666.  
  1667.     a2 = atk2[sq];
  1668.     if (a2 > 0)
  1669.       {
  1670.       a1 = atk1[sq];
  1671.       if (a1 == 0 || a2 > ctlNp + 1)
  1672.         {
  1673.         s += HUNGP;
  1674.         if (trapped (sq))
  1675.             hung[c1] += 2;
  1676.         hung[c1]++;
  1677.         }
  1678.       else if (a2 >= ctlNp || a1 < ctlP)
  1679.           s += ATAKD;
  1680.       }
  1681.  
  1682.     return (s);
  1683. }
  1684.  
  1685. static inline int
  1686. PSilverValue (register short int sq, short int side)
  1687. /*
  1688.  * Calculate the positional value for a promoted silver on 'sq'.
  1689.  */
  1690.  
  1691. {
  1692.     register short s;
  1693.     long a2, a1;
  1694.  
  1695.     s = 0;
  1696.  
  1697.     s += (KINGED + 1) * AddEnemyKingDistanceBonus(sq);
  1698.  
  1699.     a2 = atk2[sq];
  1700.     if (a2 > 0)
  1701.       {
  1702.       a1 = atk1[sq];
  1703.       if (a1 == 0 || a2 > ctlSp + 1)
  1704.         {
  1705.         s += HUNGP;
  1706.         if (trapped (sq))
  1707.             hung[c1] += 2;
  1708.         hung[c1]++;
  1709.         }
  1710.       else if (a2 >= ctlSp || a1 < ctlP)
  1711.           s += ATAKD;
  1712.       }
  1713.  
  1714.     return (s);
  1715. }
  1716.  
  1717. static inline int
  1718. PBishopValue (register short int sq, short int side)
  1719. /*
  1720.  * Calculate the positional value for a promoted bishop on 'sq'.
  1721.  */
  1722.  
  1723. {
  1724.     register short s;
  1725.     long a2, a1;
  1726.     short mob;
  1727.  
  1728.     s = Mbishop[c1][csquare(c1,sq)];
  1729.     
  1730.     if ( InPromotionZone(c1,sq) )
  1731.       s += KINGED * AddEnemyKingDistanceBonus(sq);
  1732.  
  1733.     s += BRLscan (sq, &mob);
  1734.     s += BMBLTY[mob];
  1735.     a2 = atk2[sq];
  1736.     if (a2 > 0)
  1737.       {
  1738.       a1 = atk1[sq];
  1739.       if (a1 == 0 || a2 > ctlBp + 1)
  1740.         {
  1741.         s += HUNGP;
  1742.         if (trapped (sq))
  1743.             hung[c1] += 2;
  1744.         hung[c1]++;
  1745.         }
  1746.       else if (a2 >= ctlBp || a1 < ctlP)
  1747.           s += ATAKD;
  1748.       }
  1749.  
  1750.     return (s);
  1751. }
  1752.  
  1753. static inline int
  1754. PRookValue (register short int sq, short int side)
  1755. /*
  1756.  * Calculate the positional value for a promoted rook on 'sq'.
  1757.  */
  1758.  
  1759. {
  1760.     register short s;
  1761.     register short fyle;
  1762.     long a2, a1;
  1763.     short mob;
  1764.  
  1765.     s = Mrook[c1][csquare(c1,sq)];
  1766.  
  1767.     if ( InPromotionZone(c1,sq) )
  1768.       s += KINGED * AddEnemyKingDistanceBonus(sq);
  1769.  
  1770.     s += BRLscan (sq, &mob);
  1771.     s += RMBLTY[mob];
  1772.     fyle = column (sq);
  1773.     if (PC1[fyle] == 0)
  1774.     s += RHOPN;
  1775.     if (PC2[fyle] == 0)
  1776.     s += RHOPNX;
  1777.     a2 = atk2[sq];
  1778.     if (a2 > 0)
  1779.       {
  1780.       a1 = atk1[sq];
  1781.       if (a1 == 0 || a2 > ctlRp + 1)
  1782.         {
  1783.         s += HUNGP;
  1784.         if (trapped (sq))
  1785.             hung[c1] += 2;
  1786.         hung[c1]++;
  1787.         }
  1788.       else if (a2 >= ctlRp || a1 < ctlP)
  1789.           s += ATAKD;
  1790.       }
  1791.  
  1792.     return (s);
  1793. }
  1794.  
  1795. static inline int
  1796. KingValue (register short int sq, short int side)
  1797. /*
  1798.  * Calculate the positional value for a king on 'sq'.
  1799.  */
  1800. {
  1801.     register short s;
  1802.     register short fyle;
  1803.     long a2, a1;
  1804.  
  1805.     s = Mking[c1][csquare(c1,sq)];
  1806.  
  1807. #ifdef DEBUG_EVAL
  1808.     if (debug_eval )
  1809.       fprintf(debug_eval_file,"inital value [%d] for king on %c%c: %d\n",
  1810.         csquare(c1,sq), cxx[column(sq)], rxx[row(sq)], s);
  1811. #endif
  1812.  
  1813.     if (KSFTY > 0)
  1814.     s += KingScan (sq);
  1815.  
  1816.     if (Mvboard[kingP[c1]])
  1817.     s += KMOVD;
  1818.  
  1819.     fyle = column (sq);
  1820.     if (PC1[fyle] == 0)
  1821.       {
  1822.     s += KHOPN;
  1823. #ifdef DEBUG_EVAL
  1824.         if (debug_eval )
  1825.           fprintf(debug_eval_file,"adding %d for now own pawn on file\n",
  1826.         KHOPN);
  1827. #endif
  1828.       }
  1829.     if (PC2[fyle] == 0)
  1830.       {
  1831.     s += KHOPNX;
  1832. #ifdef DEBUG_EVAL
  1833.         if (debug_eval )
  1834.           fprintf(debug_eval_file,"adding %d for now opponents pawn on file\n",
  1835.         KHOPNX);
  1836. #endif
  1837.       }
  1838.  
  1839.     a2 = atk2[sq];
  1840.     if (a2 > 0)
  1841.       {
  1842.       a1 = atk1[sq];
  1843.       if (a1 == 0 || a2 > ctlK + 1)
  1844.         {
  1845.         s += HUNGP;
  1846. #ifdef DEBUG_EVAL
  1847.         if ( debug_eval )
  1848.                   fprintf(debug_eval_file,"adding %d for hung\n", HUNGP);
  1849. #endif              
  1850.         ++hung[c1];
  1851.         }
  1852.       else
  1853.         {
  1854.           s += ATAKD;
  1855. #ifdef DEBUG_EVAL
  1856.           if ( debug_eval )
  1857.                 fprintf(debug_eval_file,"adding %d for attacked piece\n", 
  1858.                 ATAKD);
  1859. #endif              
  1860.         }
  1861.       }  
  1862.                         
  1863.     if ( in_opening_stage ) {
  1864.       /* king has moved */
  1865.       if ( GameType[c1] == STATIC_ROOK )
  1866.         {
  1867.       /* Malus for king on right side or fifth file */
  1868.           short c;
  1869.       c = 4 - ccolumn(c1,sq);
  1870.       if ( c < 0 || (c == 0 && sq != kingP[c1]) ) {
  1871.         s += c + c + OPENWRONG;
  1872. #ifdef DEBUG_EVAL
  1873.         if ( debug_eval )
  1874.         fprintf(debug_eval_file,"add %d for king on right side (Static)\n",
  1875.                 c + c + OPENWRONG);
  1876. #endif
  1877.       }
  1878.         }
  1879.       else if ( GameType[c1] == RANGING_ROOK )
  1880.         {
  1881.       /* Malusalus for king on left side or fifth file */
  1882.           short c;
  1883.       c = 4 - ccolumn(c1,sq);
  1884.        if ( c > 0 || (c == 0 && sq != kingP[c1]) ) {
  1885.         s += c + c + OPENWRONG;
  1886. #ifdef DEBUG_EVAL
  1887.         if ( debug_eval )
  1888.         fprintf(debug_eval_file,"add %d for king on left side (Ranging)\n",
  1889.                 c + c + OPENWRONG);
  1890. #endif
  1891.       }
  1892.       /* Malus for king moved before rook switch */
  1893.       if ( sq != kingP[c1] )
  1894.         if ( on_csquare(side,rook,16) ) {
  1895.         s += 4 * OPENWRONG;         
  1896. #ifdef DEBUG_EVAL
  1897.             if ( debug_eval )
  1898.             fprintf(debug_eval_file,"add %d for king moved before rook switch (Ranging)\n",
  1899.                 4 * OPENWRONG);
  1900. #endif
  1901.         }
  1902.       /* Malus for defending general moved before king switch to right side */
  1903.       if ( ccolumn(c1,sq) < 6 )
  1904.         if ( Mvboard[csquare(c1,5)] || Mvboard[csquare(c1,6)] ) {
  1905.         s += 2 * OPENWRONG;         
  1906. #ifdef DEBUG_EVAL
  1907.             if ( debug_eval )
  1908.             fprintf(debug_eval_file,
  1909.             "add %d for defending general moved before king switch (Ranging)\n",
  1910.             2 * OPENWRONG);
  1911. #endif
  1912.         }
  1913.         }                       
  1914.     }
  1915.  
  1916.     return (s);
  1917. }
  1918.  
  1919.  
  1920.  
  1921.  
  1922. #ifdef USE_PATTERN
  1923.           
  1924. short
  1925. ScorePatternDistance (register short int side)
  1926.  
  1927. /*
  1928.  * Score distance to pattern regarding the game type which side plays.
  1929.  */
  1930.  
  1931.   short ds, s = 0;
  1932.   OpeningPattern *p = NULL;
  1933.  
  1934. #ifdef DEBUG_EVAL
  1935.   if ( debug_eval )
  1936.     fprintf(debug_eval_file,"scoring castle pattern distance for PCASTLE=%d\n",
  1937.         PCASTLE);
  1938. #endif
  1939.  
  1940.   if ( PCASTLE != 0 && ((p = castle_pattern[side]) != NULL) )
  1941.     {
  1942.       ds = board_to_pattern_distance(side,p,PCASTLE,GameCnt);
  1943.       if ( ds != 0) {
  1944.         s += ds;
  1945. #ifdef DEBUG_EVAL
  1946.         if ( debug_eval && ds != 0 )
  1947.           fprintf(debug_eval_file,
  1948.             "add %d for max gain of %s to reachable castle patterns %s\n", 
  1949.             ds, ColorStr[side], p->name); 
  1950. #endif
  1951.       };
  1952.     }
  1953. #ifdef DEBUG_EVAL
  1954.   else if ( debug_eval && p == NULL )
  1955.     fprintf(debug_eval_file,"no castle pattern for %s\n",ColorStr[side]);
  1956. #endif
  1957.  
  1958. #ifdef DEBUG_EVAL
  1959.   if ( debug_eval )
  1960.     fprintf(debug_eval_file,"scoring attack pattern distance for PATTACK=%d\n",
  1961.         PATTACK);
  1962. #endif
  1963.  
  1964.   if ( PATTACK != 0 && ((p = attack_pattern[side]) != NULL) )
  1965.     {            
  1966.       ds = board_to_pattern_distance(side,p,PATTACK,GameCnt);
  1967.       if ( ds != 0 ) {
  1968.         s += ds;
  1969. #ifdef DEBUG_EVAL
  1970.         if ( debug_eval && ds != 0 )
  1971.           fprintf(debug_eval_file,
  1972.              "add %d for max gain of %s to reachable attack patterns %s\n",
  1973.              ds, ColorStr[side], p->name); 
  1974. #endif
  1975.       }
  1976.     }
  1977. #ifdef DEBUG_EVAL
  1978.   else if ( debug_eval && p == NULL )
  1979.     fprintf(debug_eval_file,"no attack pattern for %s\n",ColorStr[side]);
  1980. #endif
  1981.  
  1982.   return(s);
  1983. }
  1984.  
  1985.  
  1986. static
  1987. void
  1988. UpdatePatterns (short int side, short int GameCnt)
  1989.  
  1990. /*
  1991.  * Determine castle and attack pattern which should be reached next.
  1992.  * Only patterns are considered, which have not been reached yet.
  1993.  */
  1994.  
  1995. {
  1996.   char s[12];
  1997.   short xside = side ^ 1;
  1998.   OpeningPattern *p;
  1999. #ifdef DEBUG_EVAL
  2000.   short i;
  2001.   PatternSequence *sequence;
  2002. #endif
  2003.  
  2004.   strcpy(s,"CASTLE_?_?");
  2005.   s[7] = GameType[side];
  2006.   s[9] = GameType[xside];
  2007.   castle_pattern[side] = p = locate_opening_pattern(side,s,GameCnt);
  2008.  
  2009. #ifdef DEBUG_EVAL
  2010.   if ( debug_eval )
  2011.     if (p != NULL )
  2012.       {
  2013.         fprintf(debug_eval_file,"castle pattern of %s is %s\n",
  2014.                  ColorStr[side], p->name);
  2015.         fprintf(debug_eval_file,"reachable patterns: ");
  2016.         for (i=0,sequence=p->sequence; i<p->n; i++,sequence=sequence->next_pattern)
  2017.       if ( sequence->distance[side] != CANNOT_REACH )
  2018.         fprintf(debug_eval_file,"%d ",i);
  2019.         fprintf(debug_eval_file,"\n");
  2020.       }
  2021.     else
  2022.       {
  2023.         fprintf(debug_eval_file,"no castle pattern %s for %s\n",
  2024.                  s, ColorStr[side]);
  2025.       }
  2026. #endif
  2027.  
  2028.   strcpy(s,"ATTACK_?_?");
  2029.   s[7] = GameType[side];
  2030.   s[9] = GameType[xside];
  2031.   attack_pattern[side] = p = locate_opening_pattern(side,s,GameCnt);
  2032.   
  2033. #ifdef DEBUG_EVAL
  2034.   if ( debug_eval )
  2035.     if ( p != NULL )
  2036.       {
  2037.         fprintf(debug_eval_file,"attak pattern of %s is %s\n",
  2038.                   ColorStr[side], p->name);
  2039.         fprintf(debug_eval_file,"reachable patterns: ");
  2040.         for (i=0,sequence=p->sequence; i<p->n; i++,sequence=sequence->next_pattern)
  2041.       if ( sequence->distance[side] != CANNOT_REACH )
  2042.         fprintf(debug_eval_file,"%d ",i);
  2043.         fprintf(debug_eval_file,"\n");
  2044.       }
  2045.     else
  2046.       {
  2047.         fprintf(debug_eval_file,"no attak pattern %s for %s\n",
  2048.                   s, ColorStr[side]);
  2049.       }
  2050. #endif
  2051.  
  2052.  
  2053. }
  2054.  
  2055.  
  2056. #endif
  2057.  
  2058.  
  2059. short int
  2060. ScorePosition (register short int side)
  2061.  
  2062. /*
  2063.  * Perform normal static evaluation of board position. A score is generated
  2064.  * for each piece and these are summed to get a score for each side.
  2065.  */
  2066.  
  2067. {
  2068.     register short int score;
  2069.     register short sq, i, xside;
  2070.     short int s;
  2071.     short int escore;
  2072. #ifdef DEBUG_EVAL
  2073.     short int d;
  2074. #endif
  2075.  
  2076.     UpdateWeights ();
  2077.  
  2078. #ifdef DEBUG_EVAL
  2079.     if ( debug_eval )
  2080.       fprintf (debug_eval_file, "side = %d, stage = %d, in_opening = %d\n",
  2081.     side, stage, in_opening_stage );
  2082. #endif
  2083.  
  2084.     xside = side ^ 1;
  2085.     hung[black] = hung[white] = pscore[black] = pscore[white] = 0;
  2086.  
  2087. #ifdef CACHE
  2088. #ifdef DEBUG_EVAL
  2089.     if (debug_eval || !ProbeEETable (side, &s))
  2090. #else
  2091.     if (!ProbeEETable (side, &s))
  2092. #endif
  2093.     { 
  2094. #endif
  2095.       for (c1 = black; c1 <= white; c1++)
  2096.         {
  2097.         c2 = c1 ^ 1;
  2098.         /* atk1 is array of atacks on squares by my side */
  2099.         atk1 = atak[c1];
  2100.         /* atk2 is array of atacks on squares by other side */
  2101.         atk2 = atak[c2];
  2102.         /* same for PC1 and PC2 */
  2103.         PC1 = PawnCnt[c1];
  2104.         PC2 = PawnCnt[c2];
  2105.         for (i = PieceCnt[c1]; i >= 0; i--)
  2106.           {
  2107.               sq = PieceList[c1][i];
  2108.               switch (board[sq])
  2109.             {
  2110.             case pawn:
  2111.                 s = PawnValue (sq, side);
  2112.                 break;
  2113.             case knight:
  2114.                 s = KnightValue (sq, side);
  2115.                 break;
  2116.             case bishop:
  2117.                 s = BishopValue (sq, side);
  2118.                 break;
  2119.             case rook:
  2120.                 s = RookValue (sq, side);
  2121.                 break;
  2122.             case lance:
  2123.                 s = LanceValue (sq, side);
  2124.                 break;
  2125.             case silver:
  2126.                 s = SilverValue (sq, side);
  2127.                 break;
  2128.             case gold:
  2129.                 s = GoldValue (sq, side);
  2130.                 break;
  2131.             case ppawn:
  2132.                 s = PPawnValue (sq, side);
  2133.                 break;
  2134.             case plance:
  2135.                 s = PLanceValue (sq, side);
  2136.                 break;
  2137.             case pknight:
  2138.                 s = PKnightValue (sq, side);
  2139.                 break;
  2140.             case psilver:
  2141.                 s = PSilverValue (sq, side);
  2142.                 break;
  2143.             case pbishop:
  2144.                 s = PBishopValue (sq, side);
  2145.                 break;
  2146.             case prook:
  2147.                 s = PRookValue (sq, side);
  2148.                 break;
  2149.             case king:
  2150.                 s = KingValue (sq, side);
  2151.                 break;
  2152.             default:
  2153.                 s = 0;
  2154.                 break;
  2155.             }
  2156.               pscore[c1] += s;
  2157.               svalue[sq] = s;
  2158.           }
  2159.         }
  2160. #ifdef DEBUG_EVAL 
  2161.           if ( debug_eval ) {                      
  2162.         fprintf(debug_eval_file,"pscore[black] = %d, pscore[white] = %d\n",
  2163.         pscore[black], pscore[white]);
  2164.         debug_svalue(debug_eval_file);
  2165.       }
  2166. #endif
  2167.       if (hung[side] > 1) {
  2168. #ifdef DEBUG_EVAL
  2169.         if ( debug_eval ) {
  2170.           fprintf(debug_eval_file,"adding %d to pscore for %d hung %d pieces.\n",
  2171.           HUNGX, hung[side], side);
  2172.         }
  2173. #endif
  2174.         pscore[side] += HUNGX;
  2175.       }
  2176.       if (hung[xside] > 1) {
  2177. #ifdef DEBUG_EVAL
  2178.         if ( debug_eval ) {
  2179.           fprintf(debug_eval_file,"adding %d to pscore for %d hung %d pieces.\n",
  2180.         HUNGX, hung[xside], xside);
  2181.         }
  2182. #endif
  2183.         pscore[xside] += HUNGX;
  2184.       }
  2185.                      
  2186.           for (c1=black,c2=white; c1<=white; c1++,c2--) 
  2187.         {
  2188. #ifdef DEBUG_EVAL
  2189.           short ps0 = pscore[c1];
  2190. #endif
  2191.           /* Score fifth rank */
  2192.               for ( sq = 36; sq <= 44; sq++ ) 
  2193.             if ( color[sq] == c1 || atak[c1][sq] != 0 )
  2194.           pscore[c1]++;
  2195.  
  2196. #ifdef DEBUG_EVAL
  2197.           if ( debug_eval && ps0 != pscore[c1] )
  2198.         fprintf(debug_eval_file,"adding %d for %s's control of 5th rank\n",
  2199.               pscore[c1]-ps0, ColorStr[c1]);
  2200.           ps0 = pscore[c1];
  2201. #endif
  2202.  
  2203.           /* Score holes */
  2204.               for ( sq = ((c1==black)?0:54); sq<=((c1==black)?26:80); sq++ )
  2205.             if ( board[sq] == no_piece && atak[c1][sq] == 0 )
  2206.           pscore[c1]--;
  2207.  
  2208. #ifdef DEBUG_EVAL
  2209.           if ( debug_eval && ps0 != pscore[c1] )
  2210.         fprintf(debug_eval_file,"adding %d for holes in %s's camp\n",
  2211.               pscore[c1]-ps0, ColorStr[c1]);
  2212. #endif
  2213.  
  2214.           /* Scoring depending whether in opening stage or not */ 
  2215.  
  2216.           if ( in_opening_stage )
  2217.         {
  2218.               /* do not exchange bishops in ranging rook openings */
  2219.           if ( GameType[c1] == RANGING_ROOK )
  2220.           if ( Captured[c2][bishop] ) {
  2221.             pscore[c1] += BXCHG;
  2222. #ifdef DEBUG_EVAL   
  2223.             if ( debug_eval )
  2224.               fprintf(debug_eval_file,"adding %d for %s's bishop catched by opponent\n",
  2225.                            BXCHG, ColorStr[c1]);
  2226. #endif
  2227.           }
  2228.         }
  2229.           else
  2230.         {
  2231.           short d1 = HasPiece[c1][silver] + HasPiece[c1][gold];
  2232.           short d2 = Captured[c1][silver] + Captured[c1][gold];
  2233.               pscore[c1] += (d1*2 + d2*3) * stage / 2;
  2234. #ifdef DEBUG_EVAL 
  2235.           if ( debug_eval )
  2236.              fprintf(debug_eval_file,"adding %d for more valuable %s generals\n",
  2237.                              (d1*2 + d2*3) * stage / 2, ColorStr[c1]);
  2238. #endif
  2239.             }
  2240.         }
  2241.         
  2242.  
  2243. #ifdef USE_PATTERN
  2244.       /* Score pattern */
  2245.                    
  2246.       if ( in_opening_stage ) {    
  2247.         pscore[side]  += ScorePatternDistance (side);         
  2248.         pscore[xside] += ScorePatternDistance (xside);         
  2249.       }
  2250. #endif
  2251.  
  2252.           score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  2253.           if (dither)
  2254.               {
  2255.           if (flag.hash)
  2256.             gsrand (starttime + (unsigned int) hashbd);
  2257.           score += urand () % dither;
  2258.             }
  2259.  
  2260. #ifdef CACHE
  2261.       PutInEETable(side,score);
  2262. #endif
  2263. #ifdef DEBUG_EVAL
  2264.       if ( debug_eval )
  2265.         fprintf (debug_eval_file, "score = %d\n", score);
  2266. #endif
  2267.       return(score);
  2268. #ifdef CACHE
  2269.     }
  2270. #ifdef DEBUG_EVAL
  2271.       else
  2272.     { 
  2273.       if ( debug_eval )
  2274.         fprintf (debug_eval_file, "Score cached!\n" );
  2275.     }
  2276. #endif
  2277.                           
  2278. #ifdef DEBUG_EVAL
  2279.     if ( debug_eval )
  2280.       fprintf (debug_eval_file, "s = %d\n", s);
  2281. #endif
  2282.     return (s);
  2283. #endif
  2284. }
  2285.  
  2286.  
  2287.  
  2288.  
  2289. #define SS 1
  2290. #define RS 2
  2291. #define SR 3
  2292. #define RR 4
  2293.  
  2294.  
  2295. static
  2296.     short int *PawnAdvance[2],*LanceAdvance[2],*KnightAdvance[2],
  2297.     *SilverAdvance[2],*GoldAdvance[2],*BishopAdvance[2],*RookAdvance[2],
  2298.     *KingAdvance[2];
  2299.     
  2300.  
  2301. inline
  2302. static
  2303. void
  2304. SetOpeningStrategy(short c, short s)
  2305. #ifdef DEBUG_EVAL
  2306.   if ( debug_eval )
  2307.     fprintf(debug_eval_file,"strategy for %s is ",ColorStr[c]);
  2308. #endif                  
  2309.   if ( s == RS ) {
  2310.     PawnAdvance[c] = PawnAdvanceRS;
  2311.     LanceAdvance[c] = LanceAdvanceRS;
  2312.     KnightAdvance[c] = KnightAdvanceRS;
  2313.     SilverAdvance[c] = SilverAdvanceRS;
  2314.     GoldAdvance[c] = GoldAdvanceRS;
  2315.     BishopAdvance[c] = BishopAdvanceRS;
  2316.     RookAdvance[c] = RookAdvanceRS;
  2317.     KingAdvance[c] = KingAdvanceRS;
  2318. #ifdef DEBUG_EVAL
  2319.     if ( debug_eval )
  2320.       fprintf(debug_eval_file,"Ranging vs. Static\n");
  2321. #endif                  
  2322.   } else if ( s == SR ) {
  2323.     PawnAdvance[c] = PawnAdvanceSR;
  2324.     LanceAdvance[c] = LanceAdvanceSR;
  2325.     KnightAdvance[c] = KnightAdvanceSR;
  2326.     SilverAdvance[c] = SilverAdvanceSR;
  2327.     GoldAdvance[c] = GoldAdvanceSR;
  2328.     BishopAdvance[c] = BishopAdvanceSR;
  2329.     RookAdvance[c] = RookAdvanceSR;
  2330.     KingAdvance[c] = KingAdvanceSR;
  2331. #ifdef DEBUG_EVAL
  2332.     if ( debug_eval )
  2333.       fprintf(debug_eval_file,"Static vs. Ranging\n");
  2334. #endif                  
  2335.   } else if ( s == RR ) {
  2336.     PawnAdvance[c] = PawnAdvanceRR;
  2337.     LanceAdvance[c] = LanceAdvanceRR;
  2338.     KnightAdvance[c] = KnightAdvanceRR;
  2339.     SilverAdvance[c] = SilverAdvanceRR;
  2340.     GoldAdvance[c] = GoldAdvanceRR;
  2341.     BishopAdvance[c] = BishopAdvanceRR;
  2342.     RookAdvance[c] = RookAdvanceRR;
  2343.     KingAdvance[c] = KingAdvanceRR;
  2344. #ifdef DEBUG_EVAL
  2345.     if ( debug_eval )
  2346.       fprintf(debug_eval_file,"Ranging vs. Ranging\n");
  2347. #endif                  
  2348.   } else {
  2349.     PawnAdvance[c] = PawnAdvanceSS;
  2350.     LanceAdvance[c] = LanceAdvanceSS;
  2351.     KnightAdvance[c] = KnightAdvanceSS;
  2352.     SilverAdvance[c] = SilverAdvanceSS;
  2353.     GoldAdvance[c] = GoldAdvanceSS;
  2354.     BishopAdvance[c] = BishopAdvanceSS;
  2355.     RookAdvance[c] = RookAdvanceSS;
  2356.     KingAdvance[c] = KingAdvanceSS;
  2357. #ifdef DEBUG_EVAL
  2358.     if ( debug_eval )
  2359.       fprintf(debug_eval_file,"Static vs. Static\n");
  2360. #endif                  
  2361.   }
  2362. }
  2363.  
  2364.  
  2365.  
  2366.  
  2367. #define AssignAdvance(b,w)\
  2368. {\
  2369.   SetOpeningStrategy(black,b);\
  2370.   SetOpeningStrategy(white,w);\
  2371. }                
  2372.  
  2373.  
  2374.  
  2375. static inline void
  2376. CopyBoard (short *a, short *b, short n, short d)
  2377. {                          
  2378.     register short *sqa, *sqb, i;
  2379.  
  2380.     if ( n == d )
  2381.       bcopy(a,b,NO_SQUARES*sizeof(short));
  2382.     else 
  2383.       for (sqa = a,sqb = b,i=0; i<NO_SQUARES; sqa++,sqb++,i++)
  2384.     if ( n == 1 )
  2385.         *sqb = (*sqa) / d;
  2386.         else
  2387.       if ( d == 1 )
  2388.         *sqb = n * (*sqa);
  2389.       else
  2390.         *sqb = (n * (*sqa)) / d;
  2391. }
  2392.  
  2393.  
  2394.  
  2395. static inline void
  2396. GuessGameType (void)
  2397. {
  2398.   /*
  2399.    * Try to determine the game type of "side".
  2400.    */
  2401.  
  2402.    short side, sq, StaticRook[2] = {0,0}, RangingRook[2] = {0,0};
  2403.   
  2404.    for ( side=black; side<=white; side++ ) {         
  2405.  
  2406.      /* static rook conditions */
  2407.  
  2408.      if ( on_column(side,rook,7) )
  2409.        StaticRook[side] += 3;
  2410.      if ( on_csquare(side,pawn,34) )
  2411.        StaticRook[side] += 6;
  2412.      else if ( on_csquare(side,pawn,43) )
  2413.        StaticRook[side] += 8;
  2414.      else if ( !on_column(side,pawn,7) )
  2415.        StaticRook[side] += 5;
  2416.      if ( empty_square(side,5) || empty_square(side,6) )
  2417.        StaticRook[side] += 2;
  2418.      if ( on_left_side(side,king) )
  2419.        StaticRook[side] += 2;
  2420.  
  2421.      /* ranging rook conditions */
  2422.  
  2423.      if ( on_left_side(side,rook) )
  2424.        RangingRook[side] += 5; 
  2425.      else if ( !on_column(side,rook,7) )
  2426.        RangingRook[side] += 3;
  2427.      if ( on_csquare(side,pawn,25) )
  2428.        RangingRook[side] += 1;
  2429.      if ( on_csquare(side,pawn,30) )
  2430.        RangingRook[side] += 1;
  2431.      else
  2432.        RangingRook[side] -= 2;
  2433.      if ( on_right_side(side,king) )
  2434.        RangingRook[side] += 2;
  2435.      if ( on_csquare(side,bishop,20) )
  2436.        if ( on_csquare(side,silver,11) || on_csquare(side,silver,12) ||
  2437.         on_csquare(side,silver,21) )
  2438.        RangingRook[side] += 3;
  2439.      
  2440.      if ( StaticRook[side] > 5 || RangingRook[side] > 5 )
  2441.          GameType[side] = (StaticRook[side] > RangingRook[side]) 
  2442.                   ? STATIC_ROOK : RANGING_ROOK;
  2443.      else
  2444.          GameType[side] = UNKNOWN;
  2445.  
  2446.    }
  2447.         
  2448. #ifdef DEBUG_EVAL
  2449. #define StringOfGameType(side)\
  2450.   (GameType[side] == STATIC_ROOK ? "Static Rook" :\
  2451.   (GameType[side] == RANGING_ROOK ? "Ranging Rook" : "UNKNOWN"))
  2452.  
  2453.    if ( debug_eval )
  2454.       fprintf(debug_eval_file,"guessing game type: %s vs. %s\n",
  2455.     StringOfGameType(black), StringOfGameType(white));
  2456. #endif          
  2457.  
  2458.    if ( GameType[black] == UNKNOWN || GameType[white] == UNKNOWN )
  2459.       {
  2460.          for (side = black; side <= white; side++)
  2461.            if ( side == computer && GameType[side] == UNKNOWN ) {
  2462.             /*
  2463.               * Game type is UNKNOWN.
  2464.            * Make a decision what type of game to play.
  2465.            * To make computer games more interesting, make a
  2466.            * random decision.
  2467.            */
  2468.                if ( !on_csquare(side,pawn,25) ) {
  2469.              /* Play static rook if rook pawn has been pushed! */
  2470.              GameType[side] = STATIC_ROOK;
  2471.            } else {
  2472.              unsigned int random = urand () % 100;
  2473.              short d = StaticRook[side] - RangingRook[side];
  2474.              switch ( GameType[side ^ 1] ) {
  2475.                case STATIC_ROOK:
  2476.               if ( random < 35 + d ) GameType[side] = STATIC_ROOK;
  2477.              else if ( random < 95 ) GameType[side] = RANGING_ROOK;
  2478.              break;
  2479.                case RANGING_ROOK:
  2480.              if ( random < 75 + d) GameType[side] = STATIC_ROOK;
  2481.              else if ( random < 95 ) GameType[side] = RANGING_ROOK;
  2482.              break;
  2483.                default:          
  2484.              if ( random < 33 + d) GameType[side] = STATIC_ROOK;
  2485.              else if ( random < 66 ) GameType[side] = RANGING_ROOK;
  2486.              }       
  2487.            }
  2488. #ifdef DEBUG_EVAL
  2489.          if ( debug_eval )
  2490.                fprintf(debug_eval_file,"decide game type: %s vs. %s\n",
  2491.          StringOfGameType(black), StringOfGameType(white));
  2492. #endif
  2493.        }
  2494.       }
  2495.  
  2496. }
  2497.  
  2498.  
  2499. #ifdef DEBUG_EVAL
  2500.  
  2501. #define StringOfGameType(side)\
  2502.   (GameType[side] == STATIC_ROOK ? "Static Rook" :\
  2503.   (GameType[side] == RANGING_ROOK ? "Ranging Rook" : "UNKNOWN"))
  2504.  
  2505. #endif
  2506.  
  2507.  
  2508.  
  2509. void
  2510. ExaminePosition (void)
  2511.  
  2512. /*
  2513.  * This is done one time before the search is started. Set up arrays Mwpawn,
  2514.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  2515.  * to determine the positional value of each piece.
  2516.  */
  2517.  
  2518. {
  2519.     register short i, sq, msq;
  2520.     register short fyle;
  2521.     short wpadv, bpadv, z, side, pp, j, k, val, Pd, rank;
  2522.  
  2523.     ataks (black, atak[black]);
  2524.     ataks (white, atak[white]);
  2525.                       
  2526. #ifdef DEBUG_EVAL
  2527.     if ( debug_eval ) {
  2528.       debug_position (debug_eval_file);
  2529.       /* debug_ataks (debug_eval_file); */
  2530.     }
  2531. #endif
  2532.  
  2533.     UpdateWeights ();  
  2534.  
  2535. #ifdef NOMEMSET
  2536.     { short c, p;
  2537.       for ( c = black; c <= white; c++ )
  2538.         for ( p = pawn; p <= king; p++ )
  2539.           HasPiece[c][p] = 0;
  2540.     }
  2541. #else
  2542.     memset ((char *)HasPiece, 0,(unsigned long)sizeof(HasPiece));
  2543. #endif                             
  2544.  
  2545.     for (side = black; side <= white; side++)
  2546.     for (i = PieceCnt[side]; i >= 0; i--)
  2547.         ++HasPiece[side][board[PieceList[side][i]]];
  2548.  
  2549.     GuessGameType();
  2550.  
  2551. #ifdef USE_PATTERN
  2552.     if ( in_opening_stage ) {
  2553.       for (side = black; side <= white; side++)
  2554.         UpdatePatterns (side, GameCnt);
  2555.     }
  2556. #endif
  2557.  
  2558.     if ( GameType[black] == STATIC_ROOK) {
  2559.       if ( GameType[white] == STATIC_ROOK ) {
  2560.         /* STATIC vs. STATIC */
  2561.         AssignAdvance(SS,SS);
  2562.       } else if ( GameType[white] == RANGING_ROOK ) {
  2563.         /* STATIC vs. RANGING */
  2564.         AssignAdvance(SR,RS);
  2565.       } else {
  2566.         /* STATIC vs. ??? */
  2567.         AssignAdvance(SS,SS);
  2568.       }
  2569.     } else if ( GameType[black] == RANGING_ROOK ) {
  2570.       if ( GameType[white] == STATIC_ROOK ) {
  2571.         /* RANGING vs. STATIC */
  2572.         AssignAdvance(RS,SR);
  2573.       } else if ( GameType[white] == RANGING_ROOK ) {
  2574.         /* RANGING vs. RANGING */
  2575.         AssignAdvance(RR,RR);
  2576.       } else {
  2577.         /* RANGING vs. ???? */
  2578.         AssignAdvance(RS,SR);
  2579.       }
  2580.     } else {
  2581.       if ( GameType[white] == STATIC_ROOK ) {
  2582.         /* ???? vs. STATIC */
  2583.         AssignAdvance(SS,SS);
  2584.       } else if ( GameType[white] == RANGING_ROOK ) {
  2585.         /* ???? vs. RANGING */
  2586.         AssignAdvance(SR,RS);
  2587.       } else {
  2588.         /* ???? vs. ???? */
  2589.         AssignAdvance(SS,SS);
  2590.       }
  2591.     }
  2592.  
  2593.     /* Weighted advance tables. Can be updated. */
  2594.  
  2595.     CopyBoard (PawnAdvance[black], Mpawn[black], PADVNCM, 10);
  2596.     CopyBoard (PawnAdvance[white], Mpawn[white], PADVNCM, 10);
  2597.     CopyBoard (SilverAdvance[black], Msilver[black], SADVNCM, 10);
  2598.     CopyBoard (SilverAdvance[white], Msilver[white], SADVNCM, 10);
  2599.     CopyBoard (GoldAdvance[black], Mgold[black], GADVNCM, 10);
  2600.     CopyBoard (GoldAdvance[white], Mgold[white], GADVNCM, 10);
  2601.     CopyBoard (KingAdvance[black], Mking[black], KADVNCM, 1);
  2602.     CopyBoard (KingAdvance[white], Mking[white], KADVNCM, 1);
  2603.                       
  2604.     /* Tables without weighted advances. Must not be updated! */
  2605.  
  2606.     for ( side = black; side <= white; side++ ) {
  2607.     Mlance[side]  = LanceAdvance[side];
  2608.     Mknight[side] = KnightAdvance[side];
  2609.     Mbishop[side] = BishopAdvance[side];
  2610.     Mrook[side]   = RookAdvance[side];
  2611.     }
  2612.  
  2613. #ifdef DEBUG_EVAL
  2614.     if ( debug_eval ) {
  2615.       fprintf(debug_eval_file,"relative pawn table weigth: %d\n",PADVNCM);
  2616.       fprintf(debug_eval_file,"relative silver table weigth: %d\n",SADVNCM);
  2617.       fprintf(debug_eval_file,"relative gold table weigth: %d\n",GADVNCM);
  2618.       fprintf(debug_eval_file,"relative king table weigth: %d\n",KADVNCM);
  2619.     }
  2620. #endif
  2621.  
  2622.     /* Build up weighted enemy-king distance tables. */                                
  2623.                            
  2624.     if ( KATAK == 0 ) 
  2625. #if defined(NOMEMSET) || defined(MSDOS)
  2626.       for (sq = 0; sq < NO_SQUARES; sq++) 
  2627.     Kfield[black][sq] = Kfield[white][sq] = 0;
  2628. #else 
  2629.       memset ((char *) Kfield, 0, (unsigned long)sizeof (Kfield));
  2630. #endif /* NOMEMSET */
  2631.     else
  2632.       for (sq = 0; sq < NO_SQUARES; sq++)
  2633.         {
  2634.       Kfield[black][sq] = (distance(sq,WhiteKing)==1) ? KATAK : 0;
  2635.       Kfield[white][sq] = (distance(sq,BlackKing)==1) ? KATAK : 0;
  2636.         }
  2637.     
  2638. #ifdef DEBUG_EVAL
  2639.     if ( debug_eval )
  2640.       for (side=black; side<=white; side++)
  2641.         {
  2642.       fprintf(debug_eval_file,"%s's pawn table\n\n",ColorStr[side]);
  2643.       debug_table(debug_eval_file,Mpawn[side]);
  2644.       fprintf(debug_eval_file,"%s's silver table\n\n",ColorStr[side]);
  2645.       debug_table(debug_eval_file,Msilver[side]);
  2646.       fprintf(debug_eval_file,"%s's gold table\n\n",ColorStr[side]);
  2647.       debug_table(debug_eval_file,Mgold[side]);
  2648.       fprintf(debug_eval_file,"%s's king table\n\n",ColorStr[side]);
  2649.       debug_table(debug_eval_file,Mking[side]);
  2650.       fprintf(debug_eval_file,"%s's distance to enemy king table\n\n",ColorStr[side]);
  2651.       debug_table(debug_eval_file,Kfield[side]);
  2652.         }
  2653. #endif
  2654.  
  2655. }
  2656.  
  2657.  
  2658. void
  2659. UpdateWeights (void)
  2660.  
  2661. /*
  2662.  * If material balance has changed, determine the values for the positional
  2663.  * evaluation terms.
  2664.  */
  2665.  
  2666. {
  2667.     register short s1, dio, io, os;
  2668.  
  2669.     emtl[black] = mtl[black] - pmtl[black] - valueK;
  2670.     emtl[white] = mtl[white] - pmtl[white] - valueK;
  2671.     tmtl = emtl[black] + emtl[white];
  2672.     
  2673.     behind_in_material[black] = ((mtl[white] - mtl[black]) > valueB);
  2674.     behind_in_material[white] = ((mtl[black] - mtl[white]) > valueB);
  2675.     
  2676.     /* GameCnt = number of half moves */
  2677.     
  2678.     if (GameCnt < 21)
  2679.       s1 = 0;            /*  0 <= GameCnt <= 20: stage = 0 */
  2680.     else if (GameCnt < 41)
  2681.       s1 = 1 + (GameCnt-20)/3;    /* 21 <= GameCnt <= 40: stage = 1..7 */
  2682.     else if (GameCnt < 61)
  2683.       s1 = 8 + (GameCnt-40)/5;    /* 41 <= GameCnt <= 60: stage = 8..11 */
  2684.     else
  2685.       s1 = 12 + (GameCnt-60)/7;
  2686.     
  2687.     if (s1 != stage)
  2688.       {                   
  2689.       stage = stage2 = s1;
  2690.  
  2691.           os = (GameType[black] == STATIC_ROOK && GameType[white] == STATIC_ROOK) ? 10 : 8;
  2692.       dio = (in_opening_stage = io = (s1 < os)) ? (os - s1) : 0;
  2693.  
  2694.       PADVNCM = io?12+s1:1;    /* advanced pawn multiplier */
  2695.           PMBLTY = 5;        /* pawn mobility */
  2696.       PSTRONG = 3;         /* pawn supported by rook/lance */
  2697.       BDCLOSED = -(dio*2);    /* bishops diagonal closed by pawn */
  2698.       P2STRONG = 20;    /* attacking pawn on 2nd col is strong */
  2699.  
  2700.       LHOPN = -4;        /* no own pawn on lance file ahead */
  2701.       LHOPNX = 4;        /* no enemy pawn on lance file ahead */
  2702.       LPROTECT = 6;        /* protect own piece with lance */
  2703.       LDNGR = -4;        /* lance is in danger */
  2704.       LXRAY = 8;        /* lance Xray attack on piece */
  2705.  
  2706.       NDNGR = -4;        /* knight is in danger */
  2707.       KNIGHTPOST = 2;    /* knight near enemy pieces */
  2708.       KNIGHTSTRONG = 2;    /* occupies pawn hole */
  2709.  
  2710.       SADVNCM = io?15+s1:1;    /* advanced silver multiplier */
  2711.           SBEFOREG = 2;      /* proverb: silver before gold */
  2712.  
  2713.       GADVNCM = io?14+s1:1;    /* advanced gold multiplier */
  2714.  
  2715.       BISHOPSTRONG = 4;    /* occupies pawn hole */
  2716.       BHCLSD = -3;        /* first or second piece in a bishop's direction is an own pawn */
  2717.       BHCLSDX = -2;        /* first or second piece in a bishop's direction is an opponents pawn */                     
  2718.       BRXRAY = 10;        /* bishop or rook Xray attack on piece */
  2719.       BXCHG = -10;        /* bishop exchange in ranging rook opening */
  2720.  
  2721.       RHOPN = 10;        /* no own pawn on rook file ahead */
  2722.       RHOPNX = 8;           /* no enemy pawn on rook file ahead */
  2723.           R2NDCOL = dio*2;    /* rook is on 2nd column */
  2724.  
  2725.       PINVAL = 15;        /* Pin */
  2726.  
  2727.       KADVNCM = io?1+s1:0;    /* advanced king multiplier */
  2728.       KHOPN = -8;        /* no own pawn in kings file */
  2729.       KHOPNX = KHOPN * 2;   /* no opponents pawn in kings file */
  2730.       KCASTLD = 20;         /* king protected by castle */
  2731.       KMOVD = 4;        /* proverb: a sitting king is a sitting duck */
  2732.       KATAK = io ? 1 : 8;    /* B,R,L attacks near enemy king */
  2733.       KSFTY = 4;            /* king safety */
  2734.  
  2735.           OPENOK = dio*2;    /* corresponding to opening pattern */
  2736.           OPENWRONG = -dio*3;    /* not correpsonding */
  2737.  
  2738.           KINGOD = 2+s1/4;    /* distance to own king multiplier */
  2739.           KINGED = 3+s1/4;    /* distance to enemy king multiplier */
  2740.           PROMD = 2+s1/4;    /* distance to promotion zone multiplier */
  2741.  
  2742.       ATAKD = -15;        /* defender > attacker */
  2743.       HUNGP = -14;        /* each hung piece */
  2744.       HUNGX = -18;        /* extra for >1 hung piece */
  2745.  
  2746. #ifdef USE_PATTERN
  2747.       PATTACK = dio;     /* attack pattern distance multiplier */
  2748.       PCASTLE = dio;     /* castle pattern distance multiplier */
  2749. #endif
  2750.  
  2751.       }
  2752.  
  2753.